変数に格納された複数行の文字列を反復処理する


17

のようなものを書くのは悪いことだと読んでいfor line in $(command)ますが、代わりに正しい方法のようです:

command | while IFS= read -r line; do echo $line; done

これはうまく機能します。しかし、私が繰り返したいのは、コマンドの直接の結果ではなく、変数の内容だとしたらどうでしょうか?

たとえば、次のファイルを作成するとしますquickfox

The quick brown
foxjumps\ over -
the
lazy ,
dog.

私はこのようなことをしたいと思います:

# This is just for the example,
# I could of course stream the contents to `read`
variable=$(cat quickfox);
while IFS= read -r line < $variable; do echo $line; done; # this is incorrect

回答:


19

bashやzshのような最新のシェルには、入力として文字列を受け入れる非常に便利な `<<< 'リダイレクタがあります。だからあなたはするだろう

while IFS= read -r line ; do echo $line; done <<< "$variable"

そうでなければ、いつでもできる

echo "$variable" | while IFS= read -r line ; do echo $line; done

申し訳ありませんが、もちろん内容をエコーすることを考えるべきでした。とにかく迅速な回答をありがとう!
シェルジョン

1
$variable使用するときは二重引用符で囲む必要があります。二重引用符を使用しないと、whileループは1行の入力のみを取得します。たとえば、echo $variablevs echo "$variable"またはcat <<< $variablevsの出力の違いを参照してくださいcat <<< "$variable"
cas

@cas実際には、$ variableの内部に依存します。OP( "variable = $(cat quickfox)")で示される場合、追加の引用符なしで機能します。しかし、一般的な場合、あなたは正しい。回答を編集します。ありがとう。
lgeorget

variable=$(cat quickfox)OPの質問自体には、私が話していたものの一例を提供します。それを使用して$variable二重引用符内では、改行はシェルによってスペースに翻訳していなくて、それを使用して、改行を含んでいます。行ごとに読んで処理している場合、これは大きな違いをもたらします-前者では複数の入力行があり、後者では1行しかありません。入力データは表面的には似ていますが、実際には、これら2つのケースでは完全に異なります。
cas

たとえば、その入力データで、cat <<< "$variable" | wc -l5を cat <<< $variable | wc -l返します。1を返します。変数内の空白(改行、タブ、単一または複数のスペースを含む)を保持する場合は、変数を使用するときに二重引用符で囲む必要があります。それらはすべて、各「単語」の間の単一のスペースに変換されます。
cas
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.