🙆

シェルスクリプトでファイルやコマンドの実行結果を1行ずつ処理する

に公開

やりたいこと

シェルスクリプトでファイルやコマンドの実行結果を1行ずつ処理したい。

方法

以下のように while read を使えばよい。

ファイルの各行を処理

# ファイルの各行を処理
while IFS= read -r line; do
    echo "${line}"
done < test.txt
# 実行結果
[profile A]
credential_source = Ec2InstanceMetadata
role_arn = arn:aws:iam::111111111111:role/RoleA
role_session_name = ProfileARoleSession
[profile B]
credential_source = Ec2InstanceMetadata
role_arn = arn:aws:iam::222222222222:role/RoleB
role_session_name = ProfileBRoleSession

特定のコマンドの結果を処理

# 特定のコマンドの結果を処理
grep role_arn test.txt | while IFS= read -r line; do
    AWS_ACCOUNT_ID=$(echo "${line}" | cut -d ':' -f 5)
    echo "AWS Account ID: $AWS_ACCOUNT_ID"
done
# 実行結果
AWS Account ID: 111111111111
AWS Account ID: 222222222222

ダメな例

空白や改行が存在する場合、for では区切られてしまうため、意図しない動作となる。

# ダメな例
lines=$(cat test.txt)
for line in ${lines}; do
    echo "${line}"
done

# ダメな例2
lines=($(cat test.txt))
for line in "${lines[@]}"; do
    echo "${line}"
done
# 実行結果(どちらも同じ)
[profile
A]
credential_source
=
Ec2InstanceMetadata
role_arn
=
arn:aws:iam::111111111111:role/RoleA
role_session_name
=
ProfileARoleSession
[profile
B]
credential_source
=
Ec2InstanceMetadata
role_arn
=
arn:aws:iam::222222222222:role/RoleB
role_session_name
=
ProfileBRoleSession

Discussion