49

私はbashを学んでおり、この構造を見ました:

cat file | while IFS= read -r line;
do
    ...
done

誰が何を説明できますIFS=か?入力フィールド区切りであることは知っていますが、なぜ何も設定されていないのですか?

4

1 に答える 1

92

IFS多くのことを行いますが、その特定のループについて質問しています。

そのループの効果は、先頭と末尾の空白を保持することですline。説明するために、最初に IFS を何も設定しないで観察します。

$ echo " this   is a test " | while IFS= read -r line; do echo "=$line=" ; done
= this   is a test =

変数には、stdin で受け取ったすべてのline空白が含まれます。ここで、デフォルトの IFS を使用した同じステートメントを考えてみましょう。

$ echo " this   is a test " | while read -r line; do echo "=$line=" ; done
=this   is a test=

このバージョンでは、行の内部の空白は引き続き保持されます。ただし、先頭と末尾の空白は削除されています。

で何をし-rますread -rか?

このオプションは、バックスラッシュを特殊文字として扱う-rことを防ぎます。read

while例として、ループに 2 つの行を提供する 2 つの echo コマンドを使用します。で何が起こるか観察して-rください:

$ { echo 'this \\ line is \' ; echo 'continued'; } | while IFS= read -r line; do echo "=$line=" ; done
=this \\ line is \=
=continued=

さて、なしで何が起こるかを観察して-rください:

$ { echo 'this \\ line is \' ; echo 'continued'; } | while IFS= read line; do echo "=$line=" ; done
=this \ line is continued=

がなければ-r、2 つの変更が発生しました。まず、2 つのバックスラッシュが 1 つのバックスラッシュに変換されました。次に、最初の行の最後のバックスラッシュが行継続文字として解釈され、2 つの行が 1 つにマージされました。

つまり、入力のバックスラッシュに特別な意味を持たせたい場合は、 を使用しないでください-r。入力のバックスラッシュを普通の文字と見なしたい場合は、 を使用します-r

複数行の入力

一度に 1 行ずつ入力を受け取るためread、IFS の動作は、単一行の入力に影響を与えるのと同じように、複数行の入力の各行に影響を与えます。 -rは同様に動作しますが、 がなくても-r、上記のように末尾のバックスラッシュを使用して複数の行を 1 行にまとめることができます。

ただし、複数行入力の動作は、read の-dフラグを使用して大幅に変更できます。 入力行の終わりを示すために使用する-d区切り文字を変更します。readたとえば、タブ文字で行を終了できます。

$ echo $'line one \n line\t two \n line three\t ends here'
line one 
 line    two 
 line three      ends here
$ echo $'line one \n line\t two \n line three\t ends here' | while IFS= read -r -d$'\t' line; do echo "=$line=" ; done
=line one 
 line=
= two 
 line three=

ここでは、$'...'コンストラクトを使用して、改行、\nタブ、\t. -d$'\t'を使用すると、readタブ文字に基づいて入力が「行」に分割されることに注意してください。最後のタブ以降は無視されます。

最も難しいファイル名の処理方法

上記の機能の最も重要な用途は、難しいファイル名を処理することです。パス/ファイル名に表示できない 1 文字はヌル文字であるため、ヌル文字を使用してファイル名のリストを区切ることができます。例として:

while IFS= read -r -d $'\0' file
do
    # do something to each file
done < <(find ~/music -type f -print0)
于 2014-10-21T06:26:06.743 に答える