🐾

csvやtsvの加工・フォーマットにエクセル使わずawk使いましょう

2021/02/10に公開

大量のログファイルのフォーマットにて

同僚のエンジニアさんがこれまで、csvファイルやtsvファイルのフォーマットの際にエクセルを使われているとのことでした。
(無理な場合はvimで頑張ったりしているそうです)

そんなにサイズが大きくないファイルであればよいのですが、大量のログファイル等だと大変なので awk コマンドの簡単な使い方をお伝えすると喜んでいただけましたので、とても簡単だけど(私的に)ありがちな操作だけでも記載いたします。

awkについても素晴らしい記事がたくさんありますので、是非ご覧になってください。

https://qiita.com/yamazon/items/563af1b485ff413d381f#ofs

表示順序の変更

例えば以下のようなファイルを用意いたします。

20210209-00-01  1  complete
20210209-00-02  2  complete
20210209-00-03  3  complete
20210209-00-04  4  complete
20210209-00-05  5  complete
20210209-00-06  6  complete
20210209-00-09  7  complete
20210209-00-10  8  complete
20210209-00-100 9  complete
20210209-00-101 10 complete
20210209-00-102 11 complete
20210209-00-103 12 complete
20210209-00-105 13 complete

このファイルで表示順序を変えるには以下のようなワンライナーコマンドを打ち込むだけです。

awk '{ print $2 " " $1 " " $3 " " }' < test.txt

1 20210209-00-01 complete
2 20210209-00-02 complete
3 20210209-00-03 complete
4 20210209-00-04 complete
5 20210209-00-05 complete
6 20210209-00-06 complete
7 20210209-00-09 complete
8 20210209-00-10 complete
9 20210209-00-100 complete
10 20210209-00-101 complete
11 20210209-00-102 complete
12 20210209-00-103 complete
13 20210209-00-105 complete

出力の区切り文字を変更

スペース区切りの文字列について、tab区切りやカンマ区切りで出力したいときもワンライナーです。

OFS はOutput Field Separator の略で出力の区切りを指定できます。

カンマ区切り

awk -v 'OFS=,' '{ print $2,$1,$3 }' < test.txt

タブ区切り

awk -v 'OFS=\t' '{ print $2,$1,$3 }' < test.txt

1,20210209-00-01,complete
2,20210209-00-02,complete
3,20210209-00-03,complete
4,20210209-00-04,complete
5,20210209-00-05,complete
6,20210209-00-06,complete
7,20210209-00-09,complete
8,20210209-00-10,complete
9,20210209-00-100,complete
10,20210209-00-101,complete
11,20210209-00-102,complete
12,20210209-00-103,complete
13,20210209-00-105,complete

全フィールドをクオート等で囲んで出力

全フィールドをダブルクオートで囲む場合もワンライナーで可能です。

awk '{ gsub(/[^ ]+/,"\x22&\x22"); print }' < test.txt

"20210209-00-01"  "1"  "complete"
"20210209-00-02"  "2"  "complete"
"20210209-00-03"  "3"  "complete"
"20210209-00-04"  "4"  "complete"
"20210209-00-05"  "5"  "complete"
"20210209-00-06"  "6"  "complete"
"20210209-00-09"  "7"  "complete"
"20210209-00-10"  "8"  "complete"
"20210209-00-100" "9"  "complete"
"20210209-00-101" "10" "complete"
"20210209-00-102" "11" "complete"
"20210209-00-103" "12" "complete"
"20210209-00-105" "13" "complete"

これに先程の区切り文字も加えることで、DBにインポートしやすいcsvファイルも作れます。

awk -v 'OFS=,' '{ gsub(/[^ ]+/,"\x22&\x22"); print $2,$1,$3 }' < test.txt

"1","20210209-00-01","complete"
"2","20210209-00-02","complete"
"3","20210209-00-03","complete"
"4","20210209-00-04","complete"
"5","20210209-00-05","complete"
"6","20210209-00-06","complete"
"7","20210209-00-09","complete"
"8","20210209-00-10","complete"
"9","20210209-00-100","complete"
"10","20210209-00-101","complete"
"11","20210209-00-102","complete"
"12","20210209-00-103","complete"
"13","20210209-00-105","complete"

文字列の分割

フィールドを指定の文字列で分割して任意の部分を出力することもできます。

例えば 20210209-00-01 の部分から 最後の 01だけ取り出したい場合は以下のように入力できます。

cat test.txt | awk -v 'OFS=,' '{ split($1, array, "-"); print array[3] }'

01
02
03
04
05
06
09
10
100
101
102
103
105

今回は主に文字列処理ということで、よく使う操作をざっと並べました。

awkは簡単な計算なんかもすぐできますので、是非お困りの際は調べてみてください!!

Discussion