web-dev-qa-db-ja.com

bashスクリプトにおけるIFS = $ '\ n'の意味は何ですか?

Bashシェルスクリプトの最初にあるのは次の行です。

IFS=$'\n'

このシンボルのコレクションの背後にある意味は何ですか?

180
Abdul Al Hazred

IFSは「内部フィールドセパレーター」を表します。シェルでは、Wordの分割方法を決定するために使用されます。 e。単語の境界を認識する方法。

Bashのようなシェルでこれを試してください(他のシェルはこれを異なる方法で処理する可能性があります。たとえば、zsh)。

mystring="foo:bar baz rab"
for Word in $mystring; do
  echo "Word: $Word"
done

IFSのデフォルト値は、空白文字(正確には、スペース、タブ、改行)で構成されます。各文字はWord境界にすることができます。したがって、デフォルト値のIFSを使用すると、上記のループが出力されます。

Word: foo:bar
Word: baz
Word: rab

言い換えれば、シェルは空白はWordの境界であると考えています。

ここで、ループを実行する前にIFS=:を設定してみてください。今回の結果は次のとおりです。

Word: foo
Word: bar baz rab

現在、シェルはmystringも単語に分割しますが、現在はコロンのみを単語の境界として扱います。

IFSの最初の文字は特殊です:特殊な$*変数を使用する場合、出力内の単語を区切るために使用されます( Advanced Bash Scripting Guide からの例)、ここでそのような特殊変数に関する詳細情報も見つけることができます):

$ bash -c 'set w x y z; IFS=":-;"; echo "$*"'
w:x:y:z

と比較:

$ bash -c 'set w x y z; IFS="-:;"; echo "$*"'
w-x-y-z

どちらの例でも、シェルはすべての文字:-;をWordの境界として扱います。変更されるのは、$*の動作だけです。

もう1つ知っておくべき重要なことは、いわゆる「IFS空白」 処理される です。基本的に、IFSに空白文字が含まれるとすぐに、先頭と末尾の空白は、処理する前に分割する文字列から削除され、sequence連続する空白文字でフィールドを区切ります。ただし、これは実際にIFSに存在する空白文字にのみ適用されます。

たとえば、文字列"a:b:: c d "(末尾のスペースとcdの間の2つのスペース文字)を見てみましょう。

  1. IFS=:を使用すると、"a""b"""(空の文字列)と" c d "(再び、cおよびd)。最後のフィールドの先頭と末尾の空白に注意してください。
  2. IFS=' :'を使用すると、"a""b"""(空の文字列)、"c"および"d"の5つのフィールドに分割されます。前後の空白はどこにもありません。

2番目の例では、複数の連続する空白文字が2つのフィールドを区切るのに対して、複数の連続するコロンは区切りません(空白文字ではないため)。

IFS=$'\n'については、bashzshmkshおよびFreeBSD shでもサポートされるksh93構文です(すべてのシェル間のバリエーション)。 bashマンページの引用:

$ 'string'形式の単語は特別に扱われます。 Wordは "string"に展開され、バックスラッシュでエスケープされた文字はANSI C標準で指定されているとおりに置き換えられます。

\nは改行のエスケープシーケンスなので、IFSは単一の改行文字に設定されます。

216
Tblue

ドル記号の付いた一重引用符内では、一部の文字が特別に評価されます。例えば、 \nは新しい行に変換されます。

したがって、この特定の行は、変数IFSに改行を割り当てます。次に、IFSはbashの特別な変数である内部フィールドセパレータです。なので man bash言う、それ

展開後のWord分割と、read組み込みコマンドで行を単語に分割するために使用されます。デフォルト値は<space><tab><newline>

23
choroba

略して、IFS=$'\n'は改行\nを変数IFSに割り当てます。

$'string'構文は、エスケープシーケンスのようにANSI Cをデコードするために使用する引用メカニズムです。この構文はksh93に由来し、bashzshpdkshbusybox shなどの最新のシェルに移植できました。

この構文はPOSIXでは定義されていませんが、 SUS issue 7 で受け入れられています。

15
cuonglm