自然言語処理100本ノック 第2章 UNIXコマンドの基礎(前半)


第2章の前半の問題を解いた記録。
UNIXコマンドでの実行結果も併記。

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

## <i class="fa fa-leaf"></i> 10. 行数のカウント
> 行数をカウントせよ．確認にはwcコマンドを用いよ．

```python
# -*- coding: utf-8 -*-
__author__ = 'todoroki'

f = open('hightemp.txt')
lines = f.readlines()
print len(lines)
f.close()

#=> 24
```

対象ファイルを行ごとに読み込み、その行数を数える。

```bash
cat hightemp.txt | grep -c ""

#=> 24
```

``cat`` でテキストを表示しそれをパイプで ``grep`` に渡して行数を数える。
ちなみに、パイプの後ろの ``grep -c ""`` ではなくて ``wc -l`` でも同じように行数を数えることができるが、 ``wc`` の場合は出力にスペースが加わってしまう。
行数の出力をパイプで他の処理に渡す場合にスペースが含まれていると邪魔な場合があるので、 ``grep -c ""`` を使うほうがよい場合が多いと思われる。



## <i class="fa fa-leaf"></i> 11. タブをスペースに置換
> タブ1文字につきスペース1文字に置換せよ．確認にはsedコマンド，trコマンド，もしくはexpandコマンドを用いよ．

```python
# -*- coding: utf-8 -*-
__author__ = 'todoroki'

import re

inputfile = 'hightemp.txt'
outputfile = 'hightemp_tab2space.txt'

f = open(inputfile)
lines = f.readlines()
g = open(outputfile, 'w')
for line in lines:
    line = re.sub('\t', ' ', line)
    g.write(line)
    print line
f.close()
g.close()

#=> 高知県 江川崎 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
```

タブ文字 ``\t`` を空白に置換する。


```bash
cat hightemp.txt | tr "\t" " " > hightemp_tr.txt

#=> (出力は上と同じ)
```

## <i class="fa fa-leaf"></i> 12. 1列目をcol1.txtに，2列目をcol2.txtに保存
>各行の1列目だけを抜き出したものをcol1.txtに，2列目だけを抜き出したものをcol2.txtとしてファイルに保存せよ．確認にはcutコマンドを用いよ．

```python
# -*- coding: utf-8 -*-
__author__ = 'todoroki'

inputfile = 'hightemp.txt'
outputfile1 = 'col1.txt'
outputfile2 = 'col2.txt'
f = open(inputfile)
lines = f.readlines()
g = open(outputfile1, "w")
h = open(outputfile2, "w")
for line in lines:
    line = line.split('\t')
    g.write(line[0].strip('\n') + '\n')
    h.write(line[1].strip('\n') + '\n')
f.close()
g.close()
h.close()

# (col1.txt)
#=> 高知県
#=> 埼玉県
#=> 岐阜県
#=> 山形県
#=> 山梨県
#=> 和歌山県
#=> 静岡県
#=> 山梨県
#=> 埼玉県
#=> 群馬県
#=> 群馬県
#=> 愛知県
#=> 千葉県
#=> 静岡県
#=> 愛媛県
#=> 山形県
#=> 岐阜県
#=> 群馬県
#=> 千葉県
#=> 埼玉県
#=> 大阪府
#=> 山梨県
#=> 山形県
#=> 愛知県

# (col2.txt)
#=> 江川崎
#=> 熊谷
#=> 多治見
#=> 山形
#=> 甲府
#=> かつらぎ
#=> 天竜
#=> 勝沼
#=> 越谷
#=> 館林
#=> 上里見
#=> 愛西
#=> 牛久
#=> 佐久間
#=> 宇和島
#=> 酒田
#=> 美濃
#=> 前橋
#=> 茂原
#=> 鳩山
#=> 豊中
#=> 大月
#=> 鶴岡
#=> 名古屋
```

タブ区切りでsplitして対象をそれぞれファイルに出力

```bash
cut -f 1 hightemp.txt > hightemp_cut1.txt
cut -f 2 hightemp.txt > hightemp_cut2.txt

#=> (上と同じため出力を省略)
```

## <i class="fa fa-leaf"></i> 13. col1.txtとcol2.txtをマージ
> 12で作ったcol1.txtとcol2.txtを結合し，元のファイルの1列目と2列目をタブ区切りで並べたテキストファイルを作成せよ．確認にはpasteコマンドを用いよ．

```python
# -*- coding: utf-8 -*-
__author__ = 'todoroki'

inputfile1 = 'col1.txt'
inputfile2 = 'col2.txt'
outputfile = 'col_merge.txt'

f = open(inputfile1)
g = open(inputfile2)
h = open(outputfile, "w")

lines1 = f.readlines()
lines2 = g.readlines()
for a, b in zip(lines1, lines2):
    h.write(a.strip() + '\t' + b.strip() + '\n')
f.close()
g.close()
h.close()

#=> 高知県	江川崎
#=> 埼玉県	熊谷
#=> 岐阜県	多治見
#=> 山形県	山形
#=> 山梨県	甲府
#=> 和歌山県	かつらぎ
#=> 静岡県	天竜
#=> 山梨県	勝沼
#=> 埼玉県	越谷
#=> 群馬県	館林
#=> 群馬県	上里見
#=> 愛知県	愛西
#=> 千葉県	牛久
#=> 静岡県	佐久間
#=> 愛媛県	宇和島
#=> 山形県	酒田
#=> 岐阜県	美濃
#=> 群馬県	前橋
#=> 千葉県	茂原
#=> 埼玉県	鳩山
#=> 大阪府	豊中
#=> 山梨県	大月
#=> 山形県	鶴岡
#=> 愛知県	名古屋
```

2つのファイルを読み込み、zip関数でシーケンスオブジェクトを並行して処理。

```bash
paste col1.txt col2.txt > hightemp_paste.txt

#=> (出力は上と同じ)
```

## <i class="fa fa-leaf"></i> 14. 先頭からN行を出力
> 自然数Nをコマンドライン引数などの手段で受け取り，入力のうち先頭のN行だけを表示せよ．確認にはheadコマンドを用いよ．

```python
# -*- coding: utf-8 -*-
__author__ = 'todoroki'

import sys

if len(sys.argv) == 3:
    N = int(sys.argv[1])
    f = open(sys.argv[2])
    lines = f.readlines()
    for i in xrange(N):
        print lines[i].strip()
    f.close()
else:
    print "please input \'N\' and \'FILENAME\'"

# (python problem14.py 5 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
```

受け取った行数だけ読み取った行を出力する。

```bash
head -n 5 hightemp.txt

#=> (出力は上と同じ)
```

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">