これは私が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)
bash
zsh
ksh
a.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
答え2
bash
そうでない場合ksh93
(ksh93
シェルがbash
とにかく模倣しようとする)、組み込みオプションを使用してcsvを読むことができます-S
(read
csvスタイルの引用を理解します)。
IFS=" " read -rSA array < a.txt
printf 'a: %s\n' "${array[@]}"
これにより、変数の内容をコードのように表示するパラメータ拡張フラグ(参照は理解されますが、コードは評価されません)とパラメータ拡張フラグをzsh
使用してレベル1参照を削除できます。z
zsh
zsh
eval
Q
IFS= read -r line < a.txt
printf 'a: %s\n' "${(Q@)${(z)line}}"
(@
パラメータ拡張フラグは、動作を連想させる空の要素を保存するためのものですksh
。${array[@]}
)
a.txt
複数行が含まれている場合は、zsh
コマンドをループに置き換えることができますread
。引用符付き文字列が複数行にまたがる場合、各呼び出しは複数行を読み取ることができます。content=$(<a.txt)
ksh93
read
while
read