ファイルから読み込み、forを使用してフィールドを分割しますが、引用符は保持します。

ファイルから読み込み、forを使用してフィールドを分割しますが、引用符は保持します。

これは私がbashシェルスクリプトから得ようとしているものです:

for a in "1" "2 3" "4 5 6"
do
  echo "a: $a"
done
a: 1
a: 2 3
a: 4 5 6

ただし、変数を使用すると、引用符が異なるように処理されます。

echo "\"1\" \"2 3\" \"4 5 6\"" > a.txt

cat a.txt
"1" "2 3" "4 5 6"

read aline < a.txt

変数を二重引用符で引用すると、次の結果が表示されます。

for b in "$aline"
do
  echo "b: $b"
done
b: "1" "2 3" "4 5 6"

引用符がない場合は、次のような結果が得られます。

for b in $aline
do
  echo "b: $b"
done
b: "1"
b: "2
b: 3"
b: "4
b: 5
b: 6"

最初の例のように変数の内容を処理する方法はありますか?

ベストアンサー1

見積もりに加えて、パッケージ全体(変数/算術/コマンド拡張、ワイルドカードなど)の使用に同意する場合は、次のことができます。

echo '"a b" "x         y"' >a.txt

eval "set -- $(<a.txt)"
for b do
    printf 'b: %s\n' "$b"
done

b: a b
b: x         y

(または他の高度なシェル)ではなく、通常のシェルで機能するようにするには、に$(<a.txt)変更します。何が制御できるかわからない場合にのみ、このオプションを使用してください。そうでなければ、分割、コマンド拡張などを介してスクリプトを利用することは容易ではありません。$(cat a.txt)bashzshksha.txt;

ただし、これらのパラメータをコマンドに渡す場合は、xargs拡張なしで引用符のみを処理することを使用できます。

xargs <a.txt printf 'b: %s\n'

ただしxargs、これはシェル関数ではなく外部コマンドでのみ機能し、二重引用符内のバックスラッシュは一重引用符内のバックスラッシュのように無視され、複数行の文字列を解析できません。

後者の制限が問題にならない場合は、xargsラッパーまたは配列を介して引用パーサーとして使用できます。

mapfile -t args < <(xargs <a.txt printf '%s\n')
for b in "${args[@]}"; do
        printf 'b: %s\n' "$b"
done

おすすめ記事