経緯
仕事でよくbashを使うのだが、csvを整形して1行ずつ取り出し、sql作って投げる必要が出てきた。
久しぶりだったので、「そういえばいつもやってる方法で1行ずつ処理なんて出来るんだっけ?」と不安になり、検証しながらググってみたら意外に私のやり方でやってる人が少ないっぽいので此処に記す
whileとreadlineとか使っている人が多いようだが、慣れてないからか覚えられない&可読性低いと感じてしまう
自分がよくやる方法はbashのループ処理(forは良いぞ)と変数化で割と応用が利くやり方なので、覚えて損はないと思う
やってみる
対象のcsvファイルはこんな感じ
$cat list.csv
name,num,mail
name1,1,sample1.com
name2,2,sample2.com
name3,3,sample3.com%
このcsvファイルを$(cat list.csv)と変数にしてforに渡す
これでcat list.csv
の結果をそのまま渡すことができる
バッククォートを使って`cat list.csv`として同じことができるけど、ダブルクォーテーションとかシングルクォーテーションが入ってくると途端に可読性が落ちるし、変数展開とかエスケープとか色々面倒なので私はいつも$()を使う
count=0
for I in$(cat list.csv);do
echo"開始$((++count))"echo$Iecho"終了${count}"done
実行結果
開始1
name,number,email
終了1
開始2
name1,0001,example1.com
終了2
開始3
name2,0002,example2.com
終了3
開始4
name3,0003,example3.com
終了4
書式
for I in$(cat file.csv);do
何か処理($Iにはfile.csvの1行目が入り、1ループ毎に次の行の内容になる)
done
おまけ
$(cat file.csv)の部分はイテレータ的なものであればなんでも良いらしい
よく使うのはここら辺か
連番処理(表示するだけならecho {1..5}
とかで済む)
for I in{1..5};do
echo"私は${I}番目です"done
結果
私は1番目です
私は2番目です
私は3番目です
私は4番目です
私は5番目です
数字じゃなくても良い
for I in A B C;do
echo"私は${I}番目です"done
結果
私はA番目です
私はB番目です
私はC番目です
lsの結果を渡してカレントディレクトリのファイルを1つずつ処理するとか
$ls
a b c d
for I in$(ls);do
echo"私は${I}です"done
結果
私はaです
私はbです
私はcです
私はdです