web-dev-qa-db-ja.com

スペースを含む 'for'ループで完全な行を読み取る方法

ファイルに対してforループを実行しようとしていますが、行全体を表示したいです。ただし、代わりに最後のWordのみを表示します。完全なラインが欲しい。

for j in `cat ./file_wget_med`

do
echo $j

done

実行後の結果:

Found.

私のデータは次のとおりです。

$ cat file_wget_med
2013-09-11 14:27:03 ERROR 404: Not Found.
122
user192118

forループは、スペース、タブ、改行などの空白を検出すると分割されます。したがって、 IFS(内部フィールド区切り文字) を使用する必要があります。

IFS=$'\n'       # make newlines the only separator
for j in $(cat ./file_wget_med)    
do
    echo "$j"
done
171
Radu Rădeanu

forループは、デフォルトで任意の空白(スペース、タブ、改行)で分割されます。 lineを1つずつ処理する最も簡単な方法は、代わりにwhile readループを使用することです。これは、改行で分割されます。

while read i; do echo "$i"; done < ./file_wget_med

expectコマンドを1行に1ワード吐き出します(自分のファイルでテストしたときに何が起こったのか)。他に何かが起こっている場合、何が原因であるかはわかりません。

82
evilsoup
#!/bin/bash
files=`find <subdir> -name '*'`
while read -r fname; do
    echo $fname
done <<< "$files"

動作確認済みで、おそらく必要なライナーではありませんが、エレガントに行うことはできません。

19
Mitchell Currie

以下は、ミッチェル・カリーの答えをわずかに拡張したものです。副作用の範囲が狭いため、変数を設定する必要がないため、私はそれが好きです。

#!/bin/bash
while read -r fname; do
    echo $fname
done <<< "`find <subdir>`"
5
Dandalf

次のように書きます。

cat ./file_wget_med | while read -r j
do
    echo $j
done

元のスクリプトでの変更は最小限で済みます(IFSを使用するソリューションを除きますが、このループ制御ステートメントだけでなくbashの動作も変更します)。

1
mik