search
LoginSignup
30
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

ShellScript 【 while read 】 ファイルを1行ずつ読み込む

書式

while read 【変数名】
do
  【実行されるコマンド等】
done < 【ファイル名】

# while ~ do を1行に書く場合は do の前に ; が必要
while read 【変数名】; do
  【実行されるコマンド等】
done < 【ファイル名】

ex. クエリ結果が1行ずつJSON形式になっているファイルからCSVを作成

while read line; do
  DateTime=`echo "${line}" | jq -r '.QueryExecution.Status.SubmissionDateTime'`
  Output=`echo "${line}" | jq -r '.QueryExecution.ResultConfiguration.OutputLocation'`
  QueryId=`echo "${line}" | jq -r '.QueryExecution.QueryExecutionId'`
  Database=`echo "${line}" | jq -r '.QueryExecution.QueryExecutionContext.Database'`
  Query=`echo "${line}" | jq -r '.QueryExecution.Query'`
  echo "${DateTime},${Output},${QueryId},${Database},${Query}" >> running_queries.csv
done < all_running_queries.json # クエリ結果が1行ずつJSON形式になっているファイル(下記参照)
all_running_queries.json
{ "QueryExecution": { "Status": { "SubmissionDateTime": 111.111, "State": "RUNNING" }, "Statistics": {}, "ResultConfiguration": { "OutputLocation": "s3://aws-athena-query-results-AAA/XXX.txt" }, "QueryExecutionId": "111-AAA-XXX", "QueryExecutionContext": { "Database": "DB1" }, "Query": "SELECT * FROM table1 LIMIT 10" } }
{ "QueryExecution": { "Status": { "SubmissionDateTime": 222.222, "State": "SUCCEEDED" }, "Statistics": {}, "ResultConfiguration": { "OutputLocation": "s3://aws-athena-query-results-BBB/YYY.txt" }, "QueryExecutionId": "222-BBB-YYY", "QueryExecutionContext": { "Database": "DB2" }, "Query": "SELECT * FROM table2 LIMIT 10" } }
{ "QueryExecution": { "Status": { "SubmissionDateTime": 333.333, "State": "FAILED" }, "Statistics": {}, "ResultConfiguration": { "OutputLocation": "s3://aws-athena-query-results-CCC/ZZZ.txt" }, "QueryExecutionId": "333-CCC-ZZZ", "QueryExecutionContext": { "Database": "DB3" }, "Query": "SELECT * FROM table3 LIMIT 10" } }

>> の詳細は コマンドの標準出力をファイルに追加出力 を参照。

コマンドの実行結果を一行ずつ読み込む

【コマンド】 | while read 【変数名】; do
  【実行されるコマンド等】
done

# awk コマンドで抽出した test.csv の1~2列を1行ずつ表示
awk -F ',' '{print $1,$2}' test.csv | while read line; do
  echo "${line}"
done

# 実行結果
test.csv の1列目1行目です。 test.csv の2列目1行目です。
test.csv の1列目2行目です。 test.csv の2列目2行目です。
test.csv の1列目3行目です。 test.csv の2列目3行目です。

for文を使って複数ファイルを一行ずつ読み込む

for 【変数名1】 in 【ワイルドカード等を利用した複数ファイル名】; do
  cat 【変数名1】 | while read 【変数名2】; do
    【実行されるコマンド等】
  done
done

# ex. カレントディレクトリ内の全ファイルから先頭が 「target」 の行を all.txt にまとめる
for file in *; do
  cat "${file}" | while read line; do
    prfx=`echo "${line}" | cut -c 1-6`
    if [ "${prfx}" = 'target' ]; then
      echo "${line}" >> all.txt
    fi
  done
done

for文 の詳細は ShellScript 【 for 】を参照。

【参考】
https://lanchesters.site/bash-while-read-line/

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
30
Help us understand the problem. What are the problem?