6
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

生データファイル処理のための基本的なUnixコマンドラインツールまとめ

Posted at

データ分析業務において、データベースなどに登録されている場合は簡単に行えるようなデータの操作を、生データファイルに対して行いたい時がたびたび発生します。

今回は、そんな時に私がよく使っている、生データファイルを処理するための基本的なコマンドラインツールについて、その概要と簡単な使い方を紹介します。

cat ファイル内容を表示する

ファイルの内容を標準出力に表示するコマンドです。


$ cat sample1.csv 
都道府県名,人口(人),面積(平方km)
茨城県,2969770,6095.72
栃木県,2007683,6408.28
群馬県,2008068,6362.33
埼玉県,7194556,3798.13
千葉県,6216289,5156.7
東京都,13159388,2187.5
神奈川県,9048331,2415.86

head ファイルの先頭数行を表示する

ファイルを先頭から指定行数分だけ表示します。

ファイルサイズが大きすぎるときのちょっとしたフォーマットの確認や、ヘッダーのカラムの確認などによく使います。


$ cat sample1.csv 
都道府県名,人口(人),面積(平方km)
茨城県,2969770,6095.72
栃木県,2007683,6408.28
群馬県,2008068,6362.33
埼玉県,7194556,3798.13
千葉県,6216289,5156.7
東京都,13159388,2187.5
神奈川県,9048331,2415.86

$ head -3 sample1.csv # 先頭から3行だけ出力する
都道府県名,人口(人),面積(平方km)
茨城県,2969770,6095.72
栃木県,2007683,6408.28

$ head -1 sample1.csv # 先頭から1行だけ出力する
都道府県名,人口(人),面積(平方km)

tail ファイルの末尾数行を表示する

ファイルを末尾から指定行数分だけ表示します。

こちらもちょっとしたデータの確認のときに使ったりします。


$ cat sample1.csv 
都道府県名,人口(人),面積(平方km)
茨城県,2969770,6095.72
栃木県,2007683,6408.28
群馬県,2008068,6362.33
埼玉県,7194556,3798.13
千葉県,6216289,5156.7
東京都,13159388,2187.5
神奈川県,9048331,2415.86

$ tail -3 sample1.csv # 末尾から3行だけ出力する
千葉県,6216289,5156.7
東京都,13159388,2187.5
神奈川県,9048331,2415.86

grep 文字列を検索する

文字列の検索をします。

引数にファイル名を直接指定できますし、標準出力から検索することも多いです。


$ cat sample1.csv 
都道府県名,人口(人),面積(平方km)
茨城県,2969770,6095.72
栃木県,2007683,6408.28
群馬県,2008068,6362.33
埼玉県,7194556,3798.13
千葉県,6216289,5156.7
東京都,13159388,2187.5
神奈川県,9048331,2415.86

$ grep 都 sample1.csv # 「都」を含む行を出力する
都道府県名,人口(人),面積(平方km)
東京都,13159388,2187.5

$ cat sample1.csv | grep 都
都道府県名,人口(人),面積(平方km)
東京都,13159388,2187.5

wc 行数・単語数・バイト数を表示する

行数、単語数、バイト数の順で表示します。

単語数は空白で区切られたものを単語として扱います。

標準出力も受け取れるので、よく条件を指定して該当したデータを出力したときの件数を調べたりするときに使ったりします。


$ cat sample1.csv 
都道府県名,人口(人),面積(平方km)
茨城県,2969770,6095.72
栃木県,2007683,6408.28
群馬県,2008068,6362.33
埼玉県,7194556,3798.13
千葉県,6216289,5156.7
東京都,13159388,2187.5
神奈川県,9048331,2415.86

$ wc sample1.csv 
8 8 237 sample1.csv

$ wc -l sample1.csv # 行数のみ表示する
8 sample1.csv

$ cat sample1.csv | grep 都 | wc -l
2

cut 列を抽出する

指定列のみ出力します。

オプションで -d で区切り文字を指定(デフォルトはタブ)、 -f で列番号を指定して使うことが多いコマンドです。


$ cat sample1.csv 
都道府県名,人口(人),面積(平方km)
茨城県,2969770,6095.72
栃木県,2007683,6408.28
群馬県,2008068,6362.33
埼玉県,7194556,3798.13
千葉県,6216289,5156.7
東京都,13159388,2187.5
神奈川県,9048331,2415.86

$ cut -d , -f 2 sample1.csv # 区切り文字をカンマ、2番目の列を表示する
人口(人)
2969770
2007683
2008068
7194556
6216289
13159388
9048331

sort 行を並び替える

ソートした内容を出力します。

下記のオプションをよく使うので、これらを用いて操作します。

-t : 区切り文字を指定する。デフォルトはスペース。
-k : ソートする列番号を指定する。
-n : 列のデータを数値とみなしてソートする。
-r : 逆順にする。


$ cat sample1.csv 
都道府県名,人口(人),面積(平方km)
茨城県,2969770,6095.72
栃木県,2007683,6408.28
群馬県,2008068,6362.33
埼玉県,7194556,3798.13
千葉県,6216289,5156.7
東京都,13159388,2187.5
神奈川県,9048331,2415.86

$ sort sample1.csv 
茨城県,2969770,6095.72
群馬県,2008068,6362.33
埼玉県,7194556,3798.13
神奈川県,9048331,2415.86
千葉県,6216289,5156.7
都道府県名,人口(人),面積(平方km)
東京都,13159388,2187.5
栃木県,2007683,6408.28

$ sort -t , -k 2 -n -r sample1.csv # 区切り文字カンマ、2番目の列を数値とみなして降順ソートする(人口の多い順にソート)
東京都,13159388,2187.5
神奈川県,9048331,2415.86
埼玉県,7194556,3798.13
千葉県,6216289,5156.7
茨城県,2969770,6095.72
群馬県,2008068,6362.33
栃木県,2007683,6408.28
都道府県名,人口(人),面積(平方km)

uniq 重複した行を削除・表示する

重複した行を削除して表示します。

オプションの -c で重複している行数をカウントでき、 -d で逆に重複している行のみを出力できます。

ソート済みでないと有効にならないので注意が必要です。


$ cat sample9.csv 
都道府県名,人口(人),面積(平方km)
茨城県,2969770,6095.72
栃木県,2007683,6408.28
群馬県,2008068,6362.33
東京都,13159388,2187.5
埼玉県,7194556,3798.13
千葉県,6216289,5156.7
東京都,13159388,2187.5
神奈川県,9048331,2415.86
東京都,13159388,2187.5
群馬県,2008068,6362.33

$ sort sample9.csv | uniq # ソートをしてからでないと実行できない
茨城県,2969770,6095.72
群馬県,2008068,6362.33
埼玉県,7194556,3798.13
神奈川県,9048331,2415.86
千葉県,6216289,5156.7
都道府県名,人口(人),面積(平方km)
東京都,13159388,2187.5
栃木県,2007683,6408.28

$ sort sample9.csv | uniq -c # 行数をカウントする
      1 茨城県,2969770,6095.72
      2 群馬県,2008068,6362.33
      1 埼玉県,7194556,3798.13
      1 神奈川県,9048331,2415.86
      1 千葉県,6216289,5156.7
      1 都道府県名,人口(人),面積(平方km)
      3 東京都,13159388,2187.5
      1 栃木県,2007683,6408.28

$ sort sample9.csv | uniq -d # 重複している行のみ出力する
群馬県,2008068,6362.33
東京都,13159388,2187.5

$ sort sample9.csv | uniq -c | sort -k 1 -n -r | head -3 # 重複している順にソートして上位3つのみ出力する
      3 東京都,13159388,2187.5
      2 群馬県,2008068,6362.33
      1 栃木県,2007683,6408.28

paste 行を水平方向に連結する

2つのファイルの行を連結できます。

オプションの -d で連結する際の区切り文字を指定できます。(デフォルトはタブ)


$ cat sample91.csv 
都道府県名,人口(人)
茨城県,2969770
栃木県,2007683
群馬県,2008068
埼玉県,7194556
千葉県,6216289
東京都,13159388
神奈川県,9048331

$ cat sample92.csv 
面積(平方km)
6095.72
6408.28
6362.33
3798.13
5156.7
2187.5
2415.86

$ paste -d , sample91.csv sample92.csv # 区切り文字カンマにして、水平方向に連結
都道府県名,人口(人),面積(平方km)
茨城県,2969770,6095.72
栃木県,2007683,6408.28
群馬県,2008068,6362.33
埼玉県,7194556,3798.13
千葉県,6216289,5156.7
東京都,13159388,2187.5
神奈川県,9048331,2415.86

join 行を結合する

2つのファイルをキーを指定して結合することができます。

こちらもソート済みである必要があります。

-1 : ファイル1のキーとする列番号。
-2 : ファイル2のキーとする列番号。
-t : 区切り文字を指定する。
-a : キーの値がもう片方のファイルに存在しない行も出力する。
-v : キーの値がもう片方のファイルに存在しない行のみ出力する。


$ cat sample91.csv 
茨城県,2969770
群馬県,2008068
埼玉県,7194556
神奈川県,9048331
千葉県,6216289
東京都,13159388
栃木県,2007683

$ cat sample92.csv 
6095.72,茨城県
6362.33,群馬県
3798.13,埼玉県
2415.86,神奈川県
5156.7,千葉県
2187.5,東京都
6408.28,栃木県

$ join -t , -1 1 -2 2 sample91.csv sample92.csv # 区切り文字をカンマとし、1つ目のファイルは1番目の列、2番目のファイルは2番目の列をキーとする
茨城県,2969770,6095.72
群馬県,2008068,6362.33
埼玉県,7194556,3798.13
神奈川県,9048331,2415.86
千葉県,6216289,5156.7
東京都,13159388,2187.5
栃木県,2007683,6408.28

awk ファイルをスクリプトで処理する

大変便利なコマンドです。

列指定して抽出したり、条件指定したり、数値データを計算したり、文字列をパターンマッチしたり、とりあえず一通りのことは出来ると思います。


$ cat sample1.csv 
都道府県名,人口(人),面積(平方km)
茨城県,2969770,6095.72
栃木県,2007683,6408.28
群馬県,2008068,6362.33
埼玉県,7194556,3798.13
千葉県,6216289,5156.7
東京都,13159388,2187.5
神奈川県,9048331,2415.86

$ cat sample1.csv | awk -F , -v OFS=, '{print $2,$3}' # 入力区切り文字カンマ、出力区切り文字カンマにして2番目と3番目の列を出力する
人口(人),面積(平方km)
2969770,6095.72
2007683,6408.28
2008068,6362.33
7194556,3798.13
6216289,5156.7
13159388,2187.5
9048331,2415.86

$ awk -F , '{if($1 == "東京都" || $2 > 5000000) print}' sample1.csv # 入力区切り文字カンマで、1番目の値が東京都または2番目の値が5000000より大きい行を出力する
都道府県名,人口(人),面積(平方km)
埼玉県,7194556,3798.13
千葉県,6216289,5156.7
東京都,13159388,2187.5
神奈川県,9048331,2415.86

$ awk -F , '{sum += $2}END{print "sum:",sum,"avg:",sum/(NR-1)}' sample1.csv # 入力区切り文字カンマで、2番目の値の合計と平均(NRは行数でヘッダー分だけ引く)を表示する
sum: 42604085 avg: 6.0863e+06

q ファイルをSQLで処理する

SQLに慣れている人はこちらも使いやすいです。

CSVファイルやTSVファイルに対して、SQL文を書いてファイル処理を行なうことができます。

SQLなので一通りのデータ処理を行なうことが出来ますので、SQL得意であれば便利なコマンドかと思います。


$ cat sample1.csv 
都道府県名,人口(人),面積(平方km)
茨城県,2969770,6095.72
栃木県,2007683,6408.28
群馬県,2008068,6362.33
埼玉県,7194556,3798.13
千葉県,6216289,5156.7
東京都,13159388,2187.5
神奈川県,9048331,2415.86

$ q -O -H -d , "select * from sample1.csv where 人口(人) > 5000000" # SQLで検索する
都道府県名,人口(人),面積(平方km)
埼玉県,7194556,3798.13
千葉県,6216289,5156.7
東京都,13159388,2187.5
神奈川県,9048331,2415.86

$ cat sample1.csv | q -O -H -d , "select count(*) from -" # 標準出力はハイフンで受け取れる
count(*)
7

$ q -O -H -d , "select SUM(人口(人)) from sample1.csv" # SUMなどの関数も利用できる
SUM(人口(人))
42604085

$ q -O -H -d , "select 都道府県名,(人口(人)/面積(平方km)) as 人口密度 from sample1.csv" # 列間で計算する
都道府県名,人口密度
茨城県,487.189372215
栃木県,313.295143159
群馬県,315.618334792
埼玉県,1894.23637422
千葉県,1205.47811585
東京都,6015.72022857
神奈川県,3745.38714992

$ cat sample2.csv 
都道府県名,人口(人),面積(平方km)
滋賀県,1410777,4017.36
京都府,2636092,4613.21
大阪府,8865245,1898.47
兵庫県,5588133,8396.13
奈良県,1400728,3691.09
和歌山県,1002198,4726.29

$ q -O -H -d , "select * from sample1.csv union select * from sample2.csv order by 人口(人) desc limit 6"
都道府県名,人口(人),面積(平方km)
東京都,13159388,2187.5
神奈川県,9048331,2415.86
大阪府,8865245,1898.47
埼玉県,7194556,3798.13
千葉県,6216289,5156.7
兵庫県,5588133,8396.13

jq jsonファイルを処理する

jsonファイルを処理するときに便利なコマンドです。


$ cat sample1.json
{"data":[{"都道府県名":"茨城県","人口(人)":2969770,"面積(平方km)":6095.72},{"都道府県名":"栃木県","人口(人)":2007683,"面積(平方km)":6408.28},{"都道府県名":"群馬県","人口(人)":2008068,"面積(平方km)":6362.33},{"都道府県名":"埼玉県","人口(人)":7194556,"面積(平方km)":3798.13},{"都道府県名":"千葉県","人口(人)":6216289,"面積(平方km)":5156.7},{"都道府県名":"東京都","人口(人)":13159388,"面積(平方km)":2187.5},{"都道府県名":"神奈川県","人口(人)":9048331,"面積(平方km)":2415.86}]}

$ jq '.' sample1.json # そのまま表示する(見やすいようにインデント整形してくれる) 
{
  "data": [
    {
      "都道府県名": "茨城県",
      "人口(人)": 2969770,
      "面積(平方km)": 6095.72
    },
    {
      "都道府県名": "栃木県",
      "人口(人)": 2007683,
      "面積(平方km)": 6408.28
    },
    {
      "都道府県名": "群馬県",
      "人口(人)": 2008068,
      "面積(平方km)": 6362.33
    },
    {
      "都道府県名": "埼玉県",
      "人口(人)": 7194556,
      "面積(平方km)": 3798.13
    },
    {
      "都道府県名": "千葉県",
      "人口(人)": 6216289,
      "面積(平方km)": 5156.7
    },
    {
      "都道府県名": "東京都",
      "人口(人)": 13159388,
      "面積(平方km)": 2187.5
    },
    {
      "都道府県名": "神奈川県",
      "人口(人)": 9048331,
      "面積(平方km)": 2415.86
    }
  ]
}

$ jq '.data' sample1.json # dataキーの値を表示する
[
  {
    "都道府県名": "茨城県",
    "人口(人)": 2969770,
    "面積(平方km)": 6095.72
  },
  {
    "都道府県名": "栃木県",
    "人口(人)": 2007683,
    "面積(平方km)": 6408.28
  },
  {
    "都道府県名": "群馬県",
    "人口(人)": 2008068,
    "面積(平方km)": 6362.33
  },
  {
    "都道府県名": "埼玉県",
    "人口(人)": 7194556,
    "面積(平方km)": 3798.13
  },
  {
    "都道府県名": "千葉県",
    "人口(人)": 6216289,
    "面積(平方km)": 5156.7
  },
  {
    "都道府県名": "東京都",
    "人口(人)": 13159388,
    "面積(平方km)": 2187.5
  },
  {
    "都道府県名": "神奈川県",
    "人口(人)": 9048331,
    "面積(平方km)": 2415.86
  }
]

$ cat sample1.json | jq '.data[2]' # 標準出力からも受け取れる。dataキーの配列の3番目の値を表示する
{
  "都道府県名": "群馬県",
  "人口(人)": 2008068,
  "面積(平方km)": 6362.33
}

$ jq '.data[]|."都道府県名"' sample1.json # dataキーの配列の各要素にパイプして都道府県名キーを表示する 
"茨城県"
"栃木県"
"群馬県"
"埼玉県"
"千葉県"
"東京都"
"神奈川県"

$ cat sample1.json | jq '.data[]|."都道府県名", ."人口(人)"' # dataキーの配列の要素の各要素にパイプして都道府県名キーと人口キーの値を表示する
"茨城県"
2969770
"栃木県"
2007683
"群馬県"
2008068
"埼玉県"
7194556
"千葉県"
6216289
"東京都"
13159388
"神奈川県"
9048331

nkf 文字コードを変換する

実際にデータを操作するものではないですが、文字コードの変換は地味に使うので、こちらもよく用います。

よく使うオプションは主に下記でしょうか。

-w : UTF-8 に変換する。
-s : Shift_JIS に変換する。
-Lu : 改行コードを LF(Unix形式)に変換する。
-Lw : 改行コードを CRLF(Windows形式)に変換する。
-Lm : 改行コードを CR(Mac形式)に変換する。


$ nkf -w sample1.csv # UTF-8 に変換して表示する

$ cat sample1.csv | nkf -w # 標準出力の内容を UTF-8 に変換して表示する

od ファイル内容をバイナリ表示する

こちらも何かとお世話になるときがあります。

例えば、改行コードの確認や、データの文字列を変換したいけどもうまく変換されないときに、このコマンドを使って対象文字列のコードを確認し、コードで変換して解決したりといった使い方をしています。


$ cat sample1.csv 
都道府県名,人口(人),面積(平方km)
茨城県,2969770,6095.72
栃木県,2007683,6408.28
群馬県,2008068,6362.33
埼玉県,7194556,3798.13
千葉県,6216289,5156.7
東京都,13159388,2187.5
神奈川県,9048331,2415.86

$ od -c sample1.csv # ASCII文字で表示する
0000000 351 203 275 351 201 223 345 272 234 347 234 214 345 220 215   ,
0000020 344 272 272 345 217 243 357 274 210 344 272 272 357 274 211   ,
0000040 351 235 242 347 251 215 357 274 210 345 271 263 346 226 271   k
0000060   m 357 274 211  \n 350 214 250 345 237 216 347 234 214   ,   2
0000100   9   6   9   7   7   0   ,   6   0   9   5   .   7   2  \n 346
0000120 240 203 346 234 250 347 234 214   ,   2   0   0   7   6   8   3
0000140   ,   6   4   0   8   .   2   8  \n 347 276 244 351 246 254 347
0000160 234 214   ,   2   0   0   8   0   6   8   ,   6   3   6   2   .
0000200   3   3  \n 345 237 274 347 216 211 347 234 214   ,   7   1   9
0000220   4   5   5   6   ,   3   7   9   8   .   1   3  \n 345 215 203
0000240 350 221 211 347 234 214   ,   6   2   1   6   2   8   9   ,   5
0000260   1   5   6   .   7  \n 346 235 261 344 272 254 351 203 275   ,
0000300   1   3   1   5   9   3   8   8   ,   2   1   8   7   .   5  \n
0000320 347 245 236 345 245 210 345 267 235 347 234 214   ,   9   0   4
0000340   8   3   3   1   ,   2   4   1   5   .   8   6  \n
0000355

まとめ

以上、Unixで使えるコマンドラインツールを紹介しました。

もちろん、これらだけでなく、他にも便利なコマンドはたくさんあります。

当方のブログでは、他のコマンドなども紹介していますので、参考にして下さい。

データ分析エンジニアが気まぐれに更新するブログ - データファイル処理のためのコマンドラインツールについて

データベースに登録されていない生データファイルの確認を、以上のようなコマンドを使ってサクサクと処理して、作業を効率化させていけると便利かと思います。

6
10
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?