Categories: linux

LinuxでCSVファイルを1行ずつ読み取り処理する方法:read lineでの分解と変数代入を徹底解説

LinuxのシェルスクリプトでCSVファイルを扱う機会は多くあります。例えば、ログの集計やデータのフィルタリング、バッチ処理の自動化などでCSVを1行ずつ読み込み、それぞれのフィールドを個別の変数に分解して処理したいといったケースです。

本記事では、while read lineを使ってCSVファイルを1行ずつ読み取り、それをフィールドごとに変数に代入して処理を行う方法について、実例とともに丁寧に解説します。初心者でもすぐに実践できるよう、注意点や応用例まで取り上げています。


read lineでCSVファイルを1行ずつ読み込む基本構文

CSVファイルをシェルスクリプトで読み取る最も基本的な方法は、while read lineを使う方法です。これは以下のような構文になります。

while IFS= read -r line; do
echo "$line"
done < input.csv

このスクリプトでは、input.csvの中身を1行ずつ読み取り、line変数に代入し、それを表示しています。
IFS= はフィールドセパレータを空にして、readが先頭・末尾の空白を削除しないようにしています。
-r オプションはバックスラッシュの解釈を抑制するため、特にCSVのような生データを扱う際に便利です。


フィールドごとに変数に代入する方法

CSVファイルの各行はカンマで区切られていることが多いため、IFS=','を指定して、readコマンドで分割代入が可能です。以下に例を示します。

while IFS=',' read -r name age gender; do
echo "名前: $name"
echo "年齢: $age"
echo "性別: $gender"
done < input.csv

たとえば、input.csvに以下のようなデータが入っていた場合:

田中,30,男性
佐藤,25,女性

このスクリプトを実行すると、各行が3つの変数(name, age, gender)に分解され、それぞれの情報として出力されます。


実用的なCSV処理スクリプトの例

例:30歳以上の人だけを表示する

以下のようなCSVファイル(people.csv)があるとします。

田中,30,男性
佐藤,25,女性
鈴木,40,男性

この中から年齢が30歳以上の人だけを表示するスクリプトを作ってみましょう。

#!/bin/bash

while IFS=',' read -r name age gender; do
if [ "$age" -ge 30 ]; then
echo "$name($age歳、$gender)"
fi
done < people.csv

このスクリプトを実行すると、以下のように出力されます:

田中(30歳、男性)
鈴木(40歳、男性)

readコマンドによって行が分解され、条件に一致する行だけを処理できます。


readコマンドで注意すべきポイント

1. 最終行が処理されないことがある

CSVファイルの最終行に改行がないと、readが正しく読み込めない場合があります。これを防ぐには、CSVを保存するときに必ず最終行にも改行を入れるようにしましょう。

2. フィールド数のずれに注意

readで指定した変数の数とCSVのフィールド数が一致しない場合、余ったフィールドはすべて最後の変数にまとめて入ります。逆にフィールドが足りない場合、未指定の変数は空になります。

# 4列目が存在しないとき、locationは空になる
while IFS=',' read -r name age gender location; do
echo "$name - $location"
done < input.csv

フィールド数が不定の場合の対処法

フィールド数が可変な場合、readで指定する変数は1つだけにして、後からcutawkなどでフィールドを切り出す方法も有効です。

while IFS= read -r line; do
name=$(echo "$line" | cut -d',' -f1)
age=$(echo "$line" | cut -d',' -f2)
echo "$nameは$age歳です"
done < input.csv

あるいはawkを使えば、より簡潔に書くこともできます:

awk -F',' '{ if ($2 >= 30) print $1"さんは"$2"歳です"; }' input.csv

ループ処理の中で別の処理を組み合わせる

ループの中で外部コマンドを使ってさらに処理を加えることも可能です。たとえば、APIにデータを投げるとか、ファイル出力するなど。

while IFS=',' read -r name age gender; do
curl -X POST -d "name=$name&age=$age&gender=$gender" https://example.com/api
done < input.csv

このようにすれば、CSVの各行のデータをもとに外部サービスと連携することも可能です。


標準入力やプロセス置換と組み合わせる応用例

ファイルだけでなく、コマンドの出力結果もreadで読み込むことができます。

ps aux | while read -r line; do
echo "$line" | grep apache
done

また、プロセス置換を使えば、ファイルディスクリプタの扱いもスマートにできます。

while IFS=',' read -r name age gender; do
echo "$name($age歳、$gender)"
done < <(cat input.csv)

おわりに

while read lineを使ったCSVファイルの処理は、非常に柔軟で多用途に使えるシェルスクリプトの基本テクニックです。フィールドごとの変数代入を理解することで、CSVを自由自在に操作することができ、データ処理の幅が大きく広がります。

簡単なログ処理から業務レベルのバッチ処理まで、さまざまな場面で活用できるので、ぜひ手を動かして実践してみてください。

upandup

Web制作の記事を中心に、暮らし、ビジネスに役立つ情報を発信します。 アフィリエイトにも参加しています。よろしくお願いいたします。