問題は cat
にはありません 、 for
でも それ自体をループします。それは逆引用符を使用しています。次のいずれかを書く場合:
for i in `cat file`
または(より良い):
for i in $(cat file)
または (bash
で) ):
for i in $(<file)
シェルはコマンドを実行し、出力を文字列としてキャプチャし、$IFS
の文字で単語を区切ります . $i
に行を入力したい場合 、あなたは IFS
をいじる必要があります または while
を使用します ループ。 while
処理されるファイルが大きくなる危険性がある場合は、ループの方が適しています。 $(...)
を使用したバージョンとは異なり、一度にファイル全体をメモリに読み込む必要はありません。 .
IFS='
'
for i in $(<file)
do echo "$i"
done
"$i"
を囲む引用符 一般的には良い考えです。このコンテキストでは、変更された $IFS
を使用して 、実際には重要ではありませんが、良い習慣は良い習慣です。次のスクリプトで重要です:
old="$IFS"
IFS='
'
for i in $(<file)
do
(
IFS="$old"
echo "$i"
)
done
データ ファイルの単語間に複数のスペースが含まれている場合:
$ cat file
abc 123, comma
the quick brown fox
jumped over the lazy dog
comma, comma
$
出力:
$ sh bq.sh
abc 123, comma
the quick brown fox
jumped over the lazy dog
comma, comma
$
二重引用符なし:
$ cat bq.sh
old="$IFS"
IFS='
'
for i in $(<file)
do
(
IFS="$old"
echo $i
)
done
$ sh bq.sh
abc 123, comma
the quick brown fox
jumped over the lazy dog
comma, comma
$
IFS
を使用できます フィールドセパレーターとして改行が必要な特定の変数:
IFS=$'\n'
for i in `cat file`
do
echo $i
done
内部フィールド区切り文字 (IFS) の変更と組み合わせた for ループは、意図したとおりにファイルを読み取ります
入力用
abc 123, comma
the quick brown fox
jumped over the lazy dog
comma, comma
IFS 変更と組み合わせた for ループ
old_IFS=$IFS
IFS=$'\n'
for i in `cat file`
do
echo $i
done
IFS=$old_IFS
の結果
abc 123, comma
the quick brown fox
jumped over the lazy dog
comma, comma