hightemp.txtは,日本の最高気温の記録を「都道府県」「地点」「℃」「日」のタブ区切り形式で格納したファイルである. 以下の処理を行うプログラムを作成し,hightemp.txtを入力ファイルとして実行せよ. さらに,同様の処理をUNIXコマンドでも実行し,プログラムの実行結果を確認せよ.
行数をカウントせよ.確認にはwcコマンドを用いよ.
import sys
sys.getdefaultencoding()
'utf-8'
with open('hightemp.txt', 'r', encoding='utf-8') as file:
print(len(file.readlines()))
24
Get-Content -Encoding UTF8 .\hightemp.txt | Measure-Object -Line
or
cat -Encoding UTF8 .\hightemp.txt | Measure-Object -Line
でもいける。
タブ1文字につきスペース1文字に置換せよ.確認にはsedコマンド,trコマンド,もしくはexpandコマンドを用いよ.
with open('hightemp.txt', 'r', encoding='utf-8') as file:
#print(file.readlines())
replace_space = file.read().replace('\t', ' ')
#print(list(replace_space))
print(replace_space)
高知県 江川崎 41 2013-08-12 埼玉県 熊谷 40.9 2007-08-16 岐阜県 多治見 40.9 2007-08-16 山形県 山形 40.8 1933-07-25 山梨県 甲府 40.7 2013-08-10 和歌山県 かつらぎ 40.6 1994-08-08 静岡県 天竜 40.6 1994-08-04 山梨県 勝沼 40.5 2013-08-10 埼玉県 越谷 40.4 2007-08-16 群馬県 館林 40.3 2007-08-16 群馬県 上里見 40.3 1998-07-04 愛知県 愛西 40.3 1994-08-05 千葉県 牛久 40.2 2004-07-20 静岡県 佐久間 40.2 2001-07-24 愛媛県 宇和島 40.2 1927-07-22 山形県 酒田 40.1 1978-08-03 岐阜県 美濃 40 2007-08-16 群馬県 前橋 40 2001-07-24 千葉県 茂原 39.9 2013-08-11 埼玉県 鳩山 39.9 1997-07-05 大阪府 豊中 39.9 1994-08-08 山梨県 大月 39.9 1990-07-19 山形県 鶴岡 39.9 1978-08-03 愛知県 名古屋 39.9 1942-08-02
powershell の場合、タブ文字は \
t` を使う。
$file = Get-Content -Encoding UTF8 .\hightemp.txt
$file -replace "`t", " "
各行の1列目だけを抜き出したものをcol1.txtに,2列目だけを抜き出したものをcol2.txtとしてファイルに保存せよ.確認にはcutコマンドを用いよ.
def cut_col_lines(file_name_in:str, cut_idx:int):
with open(file_name_in, 'r', encoding='utf-8') as file_in:
col_lines = [line.split()[cut_idx] for line in file_in.readlines()]
return col_lines
def cut_col_out(file_name_in:str, cut_idx:int, file_name_out:str):
col_lines = cut_col_lines(file_name_in, cut_idx)
with open(file_name_out, 'w', encoding='utf-8') as file_out:
for line in col_lines:
file_out.write(line + '\n')
cut_col_out('hightemp.txt', 0, 'col1.txt')
cut_col_out('hightemp.txt', 1, 'col2.txt')
$file = Get-Content -Encoding UTF8 .\hightemp.txt
$f = $file -replace "`t", " "
$f | %{$_.split(" ")[0]} > col1.txt
$f | %{$_.split(" ")[1]} > col2.txt
12で作ったcol1.txtとcol2.txtを結合し,元のファイルの1列目と2列目をタブ区切りで並べたテキストファイルを作成せよ.確認にはpasteコマンドを用いよ.
def merge(filename1:str, filename2:str, filename_out:str, separate='\t'):
with open(filename1, 'r', encoding='utf-8') as file1, open(filename2, 'r', encoding='utf-8') as file2:
with open(filename_out, 'w', encoding='utf-8') as file_out:
for l1, l2 in zip(file1.readlines(), file2.readlines()):
file_out.write(l1.split()[0] + separate + l2.split()[0] + '\n')
merge('col1.txt', 'col2.txt', 'merge.txt')
windows では難しそう
自然数Nをコマンドライン引数などの手段で受け取り,入力のうち先頭のN行だけを表示せよ.確認にはheadコマンドを用いよ.
import sys
def head(filename, N=1):
with open(filename, 'r', encoding='utf-8') as file:
for i in range(N):
try:
sys.stdout.write(file.readline())
except:
sys.stderr.write('out of range')
head('col1.txt', 26)
高知県 埼玉県 岐阜県 山形県 山梨県 和歌山県 静岡県 山梨県 埼玉県 群馬県 群馬県 愛知県 千葉県 静岡県 愛媛県 山形県 岐阜県 群馬県 千葉県 埼玉県 大阪府 山梨県 山形県 愛知県
cat -Encoding UTF8 .\col1.txt -Head 25
自然数Nをコマンドライン引数などの手段で受け取り,入力のうち末尾のN行だけを表示せよ.確認にはtailコマンドを用いよ.
import sys
def tail(filename, N=1):
with open(filename, 'r', encoding='utf-8') as file:
sys.stdout.write(''.join(file.readlines()[-N:]))
tail('col1.txt', 25)
高知県 埼玉県 岐阜県 山形県 山梨県 和歌山県 静岡県 山梨県 埼玉県 群馬県 群馬県 愛知県 千葉県 静岡県 愛媛県 山形県 岐阜県 群馬県 千葉県 埼玉県 大阪府 山梨県 山形県 愛知県
cat -Encoding UTF8 .\col1.txt -Tail 2
自然数Nをコマンドライン引数などの手段で受け取り,入力のファイルを行単位でN分割せよ.同様の処理をsplitコマンドで実現せよ
import sys
import math
def split(filename:str, N=2, filename_out=False):
with open(filename, 'r', encoding='utf-8') as file:
lines = file.readlines()
idx = 0
length = len(lines)
ratio = math.ceil(length/N)
for i in range(N):
sys.stdout.writelines(lines[idx:idx + ratio])
print()
if filename_out:
with open(filename_out + str(i) + '.txt', 'w', encoding='utf-8') as file_out:
file_out.writelines(lines[idx:idx + ratio])
idx = idx + ratio
split('hightemp.txt', 6)
高知県 江川崎 41 2013-08-12 埼玉県 熊谷 40.9 2007-08-16 岐阜県 多治見 40.9 2007-08-16 山形県 山形 40.8 1933-07-25 山梨県 甲府 40.7 2013-08-10 和歌山県 かつらぎ 40.6 1994-08-08 静岡県 天竜 40.6 1994-08-04 山梨県 勝沼 40.5 2013-08-10 埼玉県 越谷 40.4 2007-08-16 群馬県 館林 40.3 2007-08-16 群馬県 上里見 40.3 1998-07-04 愛知県 愛西 40.3 1994-08-05 千葉県 牛久 40.2 2004-07-20 静岡県 佐久間 40.2 2001-07-24 愛媛県 宇和島 40.2 1927-07-22 山形県 酒田 40.1 1978-08-03 岐阜県 美濃 40 2007-08-16 群馬県 前橋 40 2001-07-24 千葉県 茂原 39.9 2013-08-11 埼玉県 鳩山 39.9 1997-07-05 大阪府 豊中 39.9 1994-08-08 山梨県 大月 39.9 1990-07-19 山形県 鶴岡 39.9 1978-08-03 愛知県 名古屋 39.9 1942-08-02
powershell の場合難しそう
$split_num = 2 # 分割
$count = 0;
$file_name = ".\hightemp.txt"
$file = cat -Encoding UTF8 $file_name
cat -Encoding UTF8 $file_name -ReadCount ($file.count / $split_num) |
ForEach-Object {
$count ++
$cfs = "{0:D3}" -f $count;
$_ > ($file_name + '_' + $cfs)
}
1列目の文字列の種類(異なる文字列の集合)を求めよ.確認にはsort, uniqコマンドを用いよ.
def cut_col_set(file_name_in:str, col_idx:int):
lines = cut_col_lines(file_name_in, col_idx)
return set(lines)
cut_col_set('hightemp.txt', 0)
{'千葉県', '和歌山県', '埼玉県', '大阪府', '山形県', '山梨県', '岐阜県', '愛媛県', '愛知県', '群馬県', '静岡県', '高知県'}
$file = Get-Content -Encoding UTF8 .\hightemp.txt
$f = $file -replace "`t", " "
$f | %{$_.split(" ")[0]} | sort | Get-Unique
各行を3コラム目の数値の逆順で整列せよ(注意: 各行の内容は変更せずに並び替えよ).確認にはsortコマンドを用いよ(この問題はコマンドで実行した時の結果と合わなくてもよい).
import sys
def sort(filename:str, col_idx=2):
with open(filename, 'r', encoding='utf-8') as file:
file_lines = [l.replace('\t', ' ') for l in file.readlines()]
# key値は関数
sys.stdout.writelines(sorted(file_lines, key=lambda l: l.split()[col_idx], reverse=True))
sort('hightemp.txt', 2)
高知県 江川崎 41 2013-08-12 埼玉県 熊谷 40.9 2007-08-16 岐阜県 多治見 40.9 2007-08-16 山形県 山形 40.8 1933-07-25 山梨県 甲府 40.7 2013-08-10 和歌山県 かつらぎ 40.6 1994-08-08 静岡県 天竜 40.6 1994-08-04 山梨県 勝沼 40.5 2013-08-10 埼玉県 越谷 40.4 2007-08-16 群馬県 館林 40.3 2007-08-16 群馬県 上里見 40.3 1998-07-04 愛知県 愛西 40.3 1994-08-05 千葉県 牛久 40.2 2004-07-20 静岡県 佐久間 40.2 2001-07-24 愛媛県 宇和島 40.2 1927-07-22 山形県 酒田 40.1 1978-08-03 岐阜県 美濃 40 2007-08-16 群馬県 前橋 40 2001-07-24 千葉県 茂原 39.9 2013-08-11 埼玉県 鳩山 39.9 1997-07-05 大阪府 豊中 39.9 1994-08-08 山梨県 大月 39.9 1990-07-19 山形県 鶴岡 39.9 1978-08-03 愛知県 名古屋 39.9 1942-08-02
# CSV を使うと楽
Import-Csv -Encoding UTF8 -Delimiter "`t" -Header "loc1", "loc2", "hight", "date" .\hightemp.txt | sort -Property hight -Descending
linuxでは、
sort -r -k 3 hoge.txt
で並び替え
各行の1列目の文字列の出現頻度を求め,その高い順に並べて表示せよ.確認にはcut, uniq, sortコマンドを用いよ.
import collections
def count_dict(filename_in:str, col_idx=0):
d = collections.defaultdict(int)
with open(filename_in, 'r', encoding='utf-8') as file:
f_lines = file.readlines()
for line in f_lines:
d[line.split()[col_idx]] += 1
return d
def count_sort(filename_in:str, col_idx=0, descending=True):
d = count_dict(filename_in, col_idx)
print(sorted(d.items(), key=lambda l:l[1], reverse=descending))
count_dict('hightemp.txt', 0)
count_sort('hightemp.txt', 0)
[('山形県', 3), ('群馬県', 3), ('山梨県', 3), ('埼玉県', 3), ('静岡県', 2), ('岐阜県', 2), ('愛知県', 2), ('千葉県', 2), ('大阪府', 1), ('和歌山県', 1), ('高知県', 1), ('愛媛県', 1)]
cat -Encoding UTF8 .\hightemp.txt | %{$_.split()[0]} | Group-Object | sort -Property count -Descending