bashシェルスクリプトの先頭には、次の行があります。
IFS=$'\n'
この記号のコレクションの背後にある意味は何ですか?
bashシェルスクリプトの先頭には、次の行があります。
IFS=$'\n'
この記号のコレクションの背後にある意味は何ですか?
回答:
IFS
「内部フィールド区切り文字」を表します。これは、単語の分割方法、つまり単語の境界を認識する方法を決定するためにシェルによって使用されます。
これをbashのようなシェルで試してみてください(他のシェルでは、zshなど、これを異なる方法で処理できます)。
mystring="foo:bar baz rab"
for word in $mystring; do
echo "Word: $word"
done
のデフォルト値IFS
は空白文字で構成されます(正確には、スペース、タブ、改行)。各文字は単語の境界にすることができます。したがって、デフォルト値のIFS
場合、上記のループは次のように出力されます。
Word: foo:bar
Word: baz
Word: rab
言い換えれば、シェルは空白が単語境界であると考えます。
ここで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
どちらの例でも、シェルはすべての文字:
、-
および;
を単語境界として処理することに注意してください。変更されるのは、の動作だけです$*
。
知っておくべきもう1つの重要なことは、いわゆる「IFSホワイトスペース」の処理方法です。基本的に、IFS
空白文字が含まれるとすぐに、先頭と末尾の空白が文字列から削除されてから処理され、一連の連続した空白文字もフィールドを区切ります。ただし、これは実際にに存在する空白文字にのみ適用されIFS
ます。
たとえば、のは、文字列を見てみましょう"a:b:: c d "
(末尾のスペースと2つのスペース文字間c
とd
)。
IFS=:
、それには次の4つのフィールドに分割されます:"a"
、"b"
、""
(空の文字列)と" c d "
(再び、二つの空間の間c
とd
)。最後のフィールドの先頭と末尾の空白に注意してください。IFS=' :'
、それは5つのフィールドに分割されます:"a"
、"b"
、""
(空の文字列)、"c"
および"d"
。どこにも先頭および末尾の空白はありません。2番目の例では、複数の連続した空白文字が2つのフィールドを区切るのに対し、複数の連続したコロンは空白文字ではないため、どのように区切られているかに注意してください。
IFS=$'\n'
つまりksh93
によってもサポートされている構文bash
、zsh
、mksh
とFreeBSD sh
(すべてのシェル間の変動を有します)。bashのマンページを引用:
$ 'string'という形式の単語は特別に扱われます。単語は「string」に展開され、ANSI C標準で指定されているように、バックスラッシュでエスケープされた文字が置き換えられます。
\n
は改行のエスケープシーケンスであるため、IFS
最終的に単一の改行文字に設定されます。
bash
スクリプトガイドなどではなく、POSIX仕様を読んで理解する方がはるかに良いでしょう。主に、そのようなリンクで利用可能な情報は重要な点で欠けています。とにかく、シェルの分割に関する2つの重要なポイント、つまりグロビングとIFSホワイトスペースを見逃しています。
unset IFS
それほど高くありませんが、好奇心が強い場合は、シェルの動作をどのように非常に異なるものにするかを調べてくださいIFS=
。また、IFSの最初のバイトも特別"${named_array[*]}"
です
$IFS
リストコンテキスト(演算子のsplit
一部)で引用符で囲まれていない変数を展開するときに実行される2つの主なものの1つですsplit+glob
。もう1つはグロビングです。作業分割を使用する場合、通常set -f
、glob
パーツを無効にするために発行する必要があります。
$IFS
またによって使用されるread
組み込みコマンド
ドル記号で囲まれた単一引用符内では、一部の文字が特別に評価されます。たとえば、\n
は新しい行に変換されます。
したがって、この特定の行は、変数IFSに改行を割り当てます。IFSは、bashの特別な変数である:内部フィールドセパレーターです。man bash
それを言います
展開後の単語分割と、
read
組み込みコマンドで行を単語に分割するために使用されます。デフォルト値は<space><tab><newline>
です。
dollared single quotes
は、単純な単一引用符とは異なります。
簡単に言えば、変数IFS=$'\n'
に改行\n
を割り当てますIFS
。
$'string'
コンストラクトは、エスケープシーケンスのようなANSI Cのデコードに使用する引用メカニズムです。この構文はから来ているksh93
、など現代の殻に移植しましたbash
、zsh
、pdksh
、busybox sh
。
この構文はPOSIXでは定義されていませんが、SUS issue 7で受け入れられました。
$IFS
例で説明し
たいと思います:cpまたはmvまたは別のファイル処理を行うSuppsoe、IFSはデフォルトで空です、ファイルにメタ文字またはスペースがある場合:
Linux Administration.pdf
またはFree Software Fundation.ogg
、 seperate paramおよびAdministartionは、separate param.Soを考慮しbuilt-in variable
ます。bashにはがありますIFS==$(echo -en "\n\b")
。その後、に初期化でき、bashはファイル名の間のメタ文字とスペースを破棄します。次に例を示します。
#!/bin/bash
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
mymusicdir=~/test/dd
find $mymusicdir -name "*" -execdir rename 's/ /_/g' "{}" +
IFS=$SAVEIFS