素人の言語処理100本ノック:11


言語処理100本ノック 2015の挑戦記録です。環境はUbuntu 16.04 LTS + Python 3.5.2 :: Anaconda 4.1.1 (64-bit)です。過去のノックの一覧はこちらからどうぞ。

第2章: UNIXコマンドの基礎

hightemp.txtは,日本の最高気温の記録を「都道府県」「地点」「℃」「日」のタブ区切り形式で格納したファイルである.以下の処理を行うプログラムを作成し,hightemp.txtを入力ファイルとして実行せよ.さらに,同様の処理をUNIXコマンドでも実行し,プログラムの実行結果を確認せよ.

11.タブをスペースに置換

タブ1文字につきスペース1文字に置換せよ.確認にはsedコマンド,trコマンド,もしくはexpandコマンドを用いよ.

出来上がったコード:

main.py
# coding: utf-8

fname = 'hightemp.txt'
with open(fname) as data_file:
    for line in data_file:
        print(line.replace('\t', ' '), end='')

実行結果:

端末
高知県 江川崎 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

UNIXコマンドの確認は、シェルスクリプトで行いました。

test.sh
#!/bin/sh

# sedのsコマンド: s/検索パターン/置換文字列/g(すべて置換)
sed 's/\t/ /g' hightemp.txt

(2018/02/10追記)
gimoさんにアドバイスいただきましたので、trコマンドとexpandコマンドの回答も追加します。

test2.sh
#!/bin/sh

# trコマンド 
tr '\t' ' ' < hightemp.txt
test3.sh
#!/bin/sh

# expandコマンド
expand --tabs=1 hightemp.txt

実行結果:

端末
高知県 江川崎 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

無事、同じ結果になりました。

ストリームの処理

今回の対象ファイルは小さいので、一気に読んで置換しても良いのかも知れません。ただ、確認に使うコマンドの筆頭にsedがあげられているので、出題の意図としてはストリーム処理を学んで欲しいのではないかと考えました。そのため、少しずつ読む形で実装しています。

sedコマンド

sedコマンドはなかなか複雑で、man sedではさっぱり分からなかったのですが、wikipediaの解説:sed (コンピュータ)で概要が把握できました。
今回使ったsedコマンドは検索パターンを正規表現で指定するのですが、タブを示す¥tはたまたま正規表現でもそのままなので、正規表現を知らなくても置換できました。正規表現はこのノックの第3章のテーマなので、そこで学んでいきます。

trコマンド

(2018/02/10追記)
trコマンドは2つの文字を指定すれば置換してくれます。対象データは標準入力から与える必要があるので、<でリダイレクトしています。詳細はmanでご確認ください。

expandコマンド

(2018/02/10追記)
expandコマンドは、タブを空白に変換するものです。既定ではタブの幅を8文字として空白に変換してしまうので、tabsオプションでタブの幅を1文字にしています。詳細はmanでご確認ください。

12本目のノックは以上です。誤りなどありましたら、ご指摘いただけますと幸いです。