BashスクリプトでIFS = $ '\ n'の意味は何ですか?

BashスクリプトでIFS = $ '\ n'の意味は何ですか?

Bash シェルスクリプトは次の行で始まります。

IFS=$'\n'

このシンボルセットの後に隠された意味は何ですか?

答え1

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ために使用されます(例:$*高度なバッシュスクリプトガイド、これらの特殊変数に関する詳細情報を見つけることもできます):

$ 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

どちらの例でも、シェルはまだすべての文字:と単語の境界を-処理します。;変化する唯一のことは行動です$*

知っておくべきもう一つの重要な点は、いわゆる「IFSブランク」がどのように実装されるかです。治療を受ける。デフォルトでは、空白文字が含まれている場合、文字列が処理される前に分割される文字列IFSから前後の空白が削除され、注文する連続した空白文字もフィールドを区別します。ただし、これは実際に存在する空白文字に対してのみ機能しますIFS

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

  1. これは、、(空の文字列)と(再び、および間に2つのスペース)IFS=:の4つのフィールドに分割されます。最後のフィールドの先頭と末尾のスペースを書き留めます。"a""b"""" c d "cd
  2. を使用すると、、、(空の文字列)とIFS=' :'の5つのフィールドに分けられます。どこにも先行および末尾のスペースはありません。"a""b""""c""d"

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

に関しては、これは、FreeBSD(すべてのシェル間で変更される)でもサポートされる構文IFS=$'\n'です。ksh93Bashのマニュアルページを引用すると、次のようになります。bashzshmkshsh

$ 'string'形式の単語は特別に扱われます。単語は、ANSI C規格で指定されているように置き換えられたバックスラッシュエスケープ文字を使用して「文字列」に拡張されます。

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

答え2

ドル一重引用符内で、特定の文字は特に評価されます。たとえば、\n新しい行に変換されます。

したがって、この行は変数IFSに改行文字を割り当てます。 IFSは、bashの特殊変数である内部フィールド区切り文字です。言ったようにman bash

拡張単語分割に使用され、組み込みreadコマンドを使用して行を単語に分割します。デフォルト値はです<space><tab><newline>

答え3

つまり、変数にIFS=$'\n'改行文字を割り当てます。\nIFS

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

この構文は POSIX では定義されていませんが、許可されます。SUS 7号

答え4

$IFS私は例えば説明することを好みます:
cp、mv、または他のファイルを処理したいSuppsoe、ファイルに次のメタ文字またはスペースがある場合、IFSはデフォルトで空です。
Linux Administration.pdfまたは、Free Software Fundation.ogg次の理由で問題が発生します。 Linuxは別々のパラメータを考慮し、管理は考慮します。単一パラメータ。したがって、 bash には があるのでbuilt-in variableで初期化でき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

関連情報