一年ぶりぐらいにAWKの練習問題を考えてみたぜw
なんか、以前の記事でも見てくれている人が多少いたんで、俺も勉強し治そうと思ったわ、ありがとー
てことで、今回のテーマは「フィールドの再構築」についてだ
AWKを使う上で覚えていて損はない部分らしいぞ
フィールドの再構築
分かりやすく言うとだな、
aaa,bbb,ccc ていうカンマ区切りの行があったとするとそれをスペース区切りaaa bbb ccc やハイフン区切りaaa-bbb-ccc
のように、レコード(一行)の区切り文字を変換するテクニックみたいなもん
じゃあ具体的どうするのかって言うと、下の通りで
1 2 |
$ echo "aaa,bbb,ccc" | awk -F ',' -v OFS=' ' '{$1 = $1; print $0;}' aaa bbb ccc |
-F でレコードの区切り文字を指定して -v OFS= の後に変換したい区切り文字を指定したあと
$1 = $1 を記述する、
$0 = $0ではだめ、$1であることが重要らしい
今回はこのテクニックを使った問題を用意したぞ
問題
サンプルテキストはこれ
1 2 3 4 5 6 7 |
数学 50 C 国語 80 B 英語 90 A 社会 100 S 理科 60 C 美術 30 D 体育 60 C |
- csv形式で出力してください
- 2列目が60以上の行をcsv形式で出力してください
- 2列目が60以上の行をcsv形式でsample.csvとして出力してください
いいでしょうか、、では解答は、こちら!
解答
csv形式で出力してください
1 2 3 4 5 6 7 8 |
$ cat sample.tsv | awk -F ' ' -v OFS=',' '{$1 = $1; print $0}' 数学,50,C 国語,80,B 英語,90,A 社会,100,S 理科,60,C 美術,30,D 体育,60,C |
上の例で言うところのOFSを","にすればいいだけだから簡単だと思う
2列目が60以上の行をcsv形式で出力してください
1 2 3 4 5 6 |
$ cat sample.tsv | awk -F ' ' -v OFS=',' '{$1 = $1; if ($2 >= 60){print $0}}' 国語,80,B 英語,90,A 社会,100,S 理科,60,C 体育,60,C |
$1=$1でフィールド再構築したあとにも、if文で絞った行のみを出力することは可能
2列目が60以上の行をcsv形式でsample.csvとして出力してください
1 2 3 4 5 6 7 |
$ cat sample.tsv | awk -F ' ' -v OFS=',' '{$1 = $1; if ($2 >= 60){print $0}}' > sample.csv $ cat sample.csv 国語,80,B 英語,90,A 社会,100,S 理科,60,C 体育,60,C |
コマンドの後に'> {ファイル名}'で出力した結果をファイルに書き込むリダイレクトのテクニックを使うことで出力した結果をそのままファイル化することが可能
ていうか、フィールド再構築とリダイレクトを組み合わせると区切り文字を変換したファイル作成が簡単にできるので知っとけばお得
とはいえ、まだまだ万能ではない
例えば、以下のテキストに対して
1 2 3 4 5 6 7 |
数学 50 'まだまだまですね もっとがんばりましょう' 国語 80 'がんばりましたね ひきつづきがんばりましょう' 英語 90 'よくできました ひきつづきどりょくをおこたらないように' 社会 100 'たいへんよくできました これからもそのちょうしで' 理科 60 'まだまだですね もっとがんばりましょう' 美術 30 'ちゃんとべんきょうしましたか? べんきょうしましょう' 体育 60 'まだまだですね もっとがんばりましょう' |
これの3列の途中のスペースを別の区切り文字に変換したくないっていうのはよくあると思う。
ちなみに、これを愚直にcsvにしようとすると
1 2 3 4 5 6 7 8 |
$ cat sample2.tsv | awk -F ' ' -v OFS=',' '{$1 = $1; print $0}' 数学,50,'まだまだまですね,もっとがんばりましょう' 国語,80,'がんばりましたね,ひきつづきがんばりましょう' 英語,90,'よくできました,ひきつづきどりょくをおこたらないように' 社会,100,'たいへんよくできました,これからもそのちょうしで' 理科,60,'まだまだですね,もっとがんばりましょう' 美術,30,'ちゃんとべんきょうしましたか?,べんきょうしましょう' 体育,60,'まだまだですね,もっとがんばりましょう' |
いやー、だめっすねーww
3列目のスペースが変換されてる・・
まあ、これをいい感じに区切り文字を変換するにはフィールド再構築のテクニックだけではだめっぽいので、これは後ほど・・
まとめ
- フィールド再構築を利用すると一行の区切り文字を別の区切り文字に変換できる
- リダイレクトとフィールド再構築を組み合わせれば、tsvをcsvやhsvに変換したファイルを作成できる
コマンドであり軽量言語(LL)の元祖でもあって、
シェルでのテキストデータ処理には便利で手放せない
「AWK」の魅力と書き方、シェルコマンドと組み合わせた
テクニック(シェル芸)を解説!