readコマンドで読み込んだ行からカラムを取り出す方法

2019-01-22Bash, Linux

今迄、 readコマンド を一行ずつ、行単位で読み込んでくりかえし処理する用途でしか使用していなかった。
ほんのちょっとだけ突っ込んだ使い方を学んだ。

行をカラム分割する

たとえば以下のようなcsvから2列目と3列目の情報を取り出す。

1,2,3,4,5
2,3,4,5,6
3,4,5,6,7
4,5,6,7,8
5,6,7,8,9

今迄のやり方

$ cat report.csv | while read line; do
  c2=$(echo "$line" | cut -d, -f 2)
  c3=$(echo "$line" | cut -d, -f 3)

  echo "$c2"
  echo "$c3"
done

結果は以下の通り

2
3
3
4
4
5
5
6
6
7

もう何が何やら

今回見つけたやり方

$ cat report.csv | while IFS=, read -r c1 c2 c3 _; do
  echo "$c2"
  echo "$c3"
done
  • read コマンドに列の区切り文字を渡す( IFS=, )
  • 列のポジションに該当する変数を列挙する
  • 不要な列位置には _ という変数を指定するのが一般的なようだ。( 意味のない変数
  • 変数には各列の値がセットされる

-r オプションは、万が一ファイルの行末にバックスラッシュが入っていた場合、改行が無視されてしまうが、無視しないようにするオプション。(なかなか無いケースとは思う)

更に、先の例の場合、c1 という変数は不要なので、以下のように記述できる。

$ cat report.csv | while IFS=, read -r _ c2 c3 _; do
  echo $c2
  echo $c3
done

ちなみに出力だけが目的であれば...

ただしここまで見てきた例はあくまでも whileループ内で複雑なロジックを組みたい場合の方法
ただ 2列目、3列目を出力したいだけの場合にはもっと簡単に実現できる。

$ cat report.csv | cut -d, -f2,3 | tr ',' "\n"

2019-01-22Bash, Linux