【言語処理100本ノック解いてみた】 第2章:UNIXコマンド No.10~No.19

プログラミング

はじめに

今回は第2章の問題を解いていきたいと思います.
主にコマンドによるファイルの中身の操作方法をこの章で学ぶことができます.
また,2章以降はGoogle Colaboraroryでの実行を想定したコードになっていますので,コマンドを試しながら進めたい方は環境を揃えるようによろしくお願いします.
では,早速解いていきたいと思います.

準備

2章では既に用意されたファイルをダウンロードし,そのファイルをコマンドで操作します.
使用するファイルはpopular-names.txtでアメリカで生まれた赤ちゃんの「名前」「性別」「人数」「年」をタブ区切り形式で格納したファイルです.
指定された処理を行うプログラムを作成するよう指示されていますが,本サイトではコマンドでの実装方法の記載が主になります.
では,まず初めにファイルのダウンロードからしていきましょう.

!wget https://nlp100.github.io/data/popular-names.txt

上記のコマンドを実行するとcolabのファイルの中にpopular-names.txtが入ってくるかと思います.
このファイルを操作しながら以降の問題を解いていきます.

10. 行数のカウント

問題文:行数をカウントせよ.確認にはwcコマンドを用いよ.
コマンド
!wc -l popular-names.txt

出力

2780 popular-names.txt
解説

wc ファイル名 と入力することでそのファイル内の行数,単語数,バイト数を知ることができます.
引数に”-l”をつけることで行数を表示することができます. 詳しくはこちらを参考にするといいと思います.

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

問題文:
タブ1文字につきスペース1文字に置換せよ.確認にはsedコマンド,trコマンド,もしくはexpandコマンドを用いよ.
コマンド
!sed -e 's/\t/ /g' popular-names.txt |head -n 5

出力

Mary F 7065 1880
Anna F 2604 1880
Emma F 2003 1880
Elizabeth F 1939 1880
Minnie F 1746 1880
解説

sedコマンドは文字列を置換するためのコマンドになります.
sed -e ‘s/置換前/置換後/g’ ファイル名 とすることでファイル内の文字列を置換することができます.
今回の目的はtab区切りを空白区切りに変えるということなので置換前の部分に”\t”を置換後の部分に” “を入れることで問題を解くことができます.
置換できたかの確認にはheadコマンドを使用しています.
また,”|”はコマンド同士を繋げて左のコマンドの結果を受けて右のコマンドに引き渡す役割があります.他にもコマンドをつなげる方法がありますのでこちらを参考にしてください.
trコマンド,expandコマンドでのやり方も紹介しておきます.

trコマンド例
!cat popular-names.txt | tr "\t" " " | head -n 5
expandコマンド例
!expand -t 1 popular-names.txt | head -n 5

12. 1列目をcol1.txtに,2列目をcol2.txtに保存

問題文:
各行の1列目だけを抜き出したものをcol1.txtに,2列目だけを抜き出したものをcol2.txtとしてファイルに保存せよ.確認にはcutコマンドを用いよ.
コマンド
!cut -f 1 popular-names.txt > cut1.txt | head -n 5 cut1.txt
!cut -f 2 popular-names.txt > cut2.txt | head -n 5 cut2.txt
解説

cutコマンドではデフォルトでタブ区切りになっています.
“-d”の引数によって区切り文字を変更することができます.
“-f”の引数は列の指定になるので,今回の問題では1列目と2列目を指定し,新しいファイルに書き出しています.

13. col1.txtとcol2.txtをマージ

問題文:
12で作ったcol1.txtとcol2.txtを結合し,元のファイルの1列目と2列目をタブ区切りで並べたテキストファイルを作成せよ.確認にはpasteコマンドを用いよ.
コード
!paste cut1.txt cut2.txt | head -n 5 

出力

Mary	F
Anna	F
Emma	F
Elizabeth	F
Minnie	F
解説

pasteコマンドは結合するファイル毎の行単位で値を取得し,タブ区切りで出力するコマンドになります.
-dのオプションを使うことで区切り文字を変更することもできます.
今回は単純にタブ区切りにしてファイルを作成するだけなので純粋にpaste+ファイル名で目的のファイルを作成することができます.

14. 先頭からN行を出力

問題文:
自然数Nをコマンドライン引数などの手段で受け取り,入力のうち先頭のN行だけを表示せよ.確認にはheadコマンドを用いよ.
コード
!head -n 5 popular-names.txt

出力

Mary	F	7065	1880
Anna	F	2604	1880
Emma	F	2003	1880
Elizabeth	F	1939	1880
Minnie	F	1746	1880
解説

今まで解説せずに使ってきたheadコマンドの使い方ですね.
-nのオプションで先頭から何行持ってくるかを指定することができます.

15. 末尾のN行を出力

問題文:
自然数Nをコマンドライン引数などの手段で受け取り,入力のうち末尾のN行だけを表示せよ.確認にはtailコマンドを用いよ.
コード
!tail -n 5 popular-names.txt

出力

Benjamin	M	13381	2018
Elijah	M	12886	2018
Lucas	M	12585	2018
Mason	M	12435	2018
Logan	M	12352	2018
解説

headコマンドのお仲間のtailコマンドの使い方に関してです.
基本的な使い方はheadと同様です.
ファイルの末尾から何行持ってくるかを-nのオプションを使って指定します.

16. ファイルをN分割する

問題文:
自然数Nをコマンドライン引数などの手段で受け取り,入力のファイルを行単位でN分割せよ.同様の処理をsplitコマンドで実現せよ.
コード
!split -l 100 -d popular-names.txt popular-names-split

出力

#popular-names-split00
#         :
#popular-names-split27
解説

splitコマンドは-lのオプションで指定した行数毎に対象ファイルを分割することができます.
-dのオプションは作成されたファイル名に数字を割り当ててくれるオプションになります.
”split -l 行数 -d split対象のファイル 出力ファイル名”のコマンドイメージです.
100行毎の分割でも27ファイル作成されてしまうので行数は500とかにしてみてもいいかもしれませんね.

17. 1列目の文字列の異なり

問題文:
1列目の文字列の種類(異なる文字列の集合)を求めよ.確認にはcut, sort, uniqコマンドを用いよ.
コード
!cut -f 1 popular-names.txt |sort |uniq | wc -l

出力

136
解説

だんだん問題が難しくなってきましたね….
今回の問題は今まで学んだコマンド+並び替えできるかという部分がキーポイントになるかと思います.
まず,cutコマンドでpopular-names.txtの一列目を取得します.
次に,sortコマンドで一列目の値を並び替えます(uniqコマンドは並び替え済みであることを前提としているため).
その後,uniqコマンドによって並び替え済みの値で重複している部分を削除します.
最後に,wcコマンドで列数を数えてあげれば何種類のユニークな文字列があるか求めることができます.
sortしてからでないとuniqコマンドの意味がないということは覚えておきましょう.

18. 各行を3コラム目の数値の降順にソート

問題文:
各行を3コラム目の数値の逆順で整列せよ(注意: 各行の内容は変更せずに並び替えよ).確認にはsortコマンドを用いよ(この問題はコマンドで実行した時の結果と合わなくてもよい).
コード
!sort -k 3nr -t $'\t' popular-names.txt | head -n 5

出力

Linda	F	99689	1947
Linda	F	96211	1948
James	M	94757	1947
Michael	M	92704	1957
Robert	M	91640	1947
解説

先ほど出てきたsortの使い方の応用編ですね.
それぞれのオプションについて説明していきます.
まず,-kのオプションに関しては何列目を並び替えるか指示するものになります.
また,引数として与えられている”3nr”というのは”3列目を数字(n)の逆順(r)で”という意味になります.
-tのオプションは区切り文字の指定になります.
今回はtab区切りにしたいので $’\t’ を使って指定します.
コマンドの引数に関する知識が求められてきましたが,sortコマンドを調べるとたくさん参考になる使い方が出てくるので確認しながら進めましょう.

19. 各行の1コラム目の文字列の出現頻度を求め,出現頻度の高い順に並べる

問題文:
各行の1列目の文字列の出現頻度を求め,その高い順に並べて表示せよ.確認にはcut, uniq, sortコマンドを用いよ.
コード
!cut -f 1 popular-names.txt |sort |uniq -c |sort -rn |head -n 10

出力

    118 James
    111 William
    108 Robert
    108 John
     92 Mary
     75 Charles
     74 Michael
     73 Elizabeth
     70 Joseph
     60 Margaret
解説

2章で学んだコマンドの総復習のような問題でしたね.
順番に紐解いていけば,これまでの知識で解いていくことができます.
コマンドの流れ以下のようになっています.

  1. cutコマンドで一列目の抽出
  2. sortコマンドで文字列の並び替え
  3. uniq -c で文字列の出現頻度の算出
  4. sort -rn で出現頻度を逆順で取得

終わりに

2章では主にUNIXコマンドを用いたファイルの操作に関して学んできました.
自然言語処理では分析だけではなくデータを集めることも自分でしなければならない場面が出てきます.
2章で学んだ知識でぜひ必要な情報を取得できるようになってください.
では,次回の第3章でお会いしましょう.

次の記事

前の記事

コメント

タイトルとURLをコピーしました