bashは、「IFS」変数の値に応じて動作を変更します


18

IFS変数をスペースに設定すると、bash複数のスペースを1つのスペースとして扱います(myprogram受け取ったコマンドライン引数を出力するプログラムです)。

IFS=" "
x="hello   hi   world"
./myprogram $x
argv[1] = hello
argv[2] = hi
argv[3] = world

しかし、IFS変数をコンマに設定すると、bash複数のコンマが1つのコンマとして扱われません。

IFS=","
x="hello,,,hi,,,world"
./myprogram $x
argv[1] = hello
argv[2] = 
argv[3] = 
argv[4] = hi
argv[5] = 
argv[6] = 
argv[7] = world

何故ですか?


参考のために、「IFS」は内部フィールド区切り文字を意味します。
pr1268

回答:


21

これはに文書化されていman bashます。IFSで空白以外の文字が1回出現すると、フィールドが区切られます。

からman bash

シェルは、IFSの各文字を区切り文字として扱い、これらの文字をフィールドターミネータとして使用して、他の展開の結果を単語に分割します。IFSが設定されていない、またはその値が正確である場合は<space><tab><newline>、デフォルトでは、その後の配列<space><tab>および<newline>以前の拡張の結果の開始時と終了時に無視され、先頭または末尾にIFS文字の任意のシーケンスではないが、区切るためのもの言葉。IFSにデフォルト以外の値がある場合、空白文字がIFS(IFS空白文字)の値にある限り、空白文字、スペース、タブ、および改行のシーケンスは単語の先頭と末尾で無視されます)。 IFS空白以外のIFSの文字は、隣接するIFS空白文字とともにフィールドを区切ります。IFS空白文字のシーケンスも区切り文字として扱われます。 IFSの値がnullの場合、単語分割は発生しません。[エンファシスが追加されました。]

例:フィールド分割

IFSに空白文字がない場合、フィールドに空白が含まれます。

$ ( IFS=',' x='one , two,three'; printf "<%s>\n" $x )
<one >
< two>
<three>

IFSにブランクとコンマの両方がある場合、ブランクのシーケンス、コンマ、ブランクのシーケンスの順に単一の区切り文字として扱われます。

$ ( IFS=' ,' x='one , two,three'; printf "<%s>\n" $x )
<one>
<two>
<three>

コンマのシーケンスは、空のフィールドのシーケンスとして解釈されます。

$ ( IFS=' ,' x='one,,,two,three'; printf "<%s>\n" $x )
<one>
<>
<>
<two>
<three>

例:先頭および末尾の空白

IFSに空白が含まれていない場合、フィールドの先頭および末尾の空白は保持されます。

$ ( IFS=',' x='  one , two,three  ,'; printf "<%s>\n" $x )
<  one >
< two>
<three  >

IFSに空白が含まれている場合、空白の先頭または末尾のシーケンスは削除されます。

$ ( IFS=' ,' x='  one , two,three  ,'; printf "<%s>\n" $x )
<one>
<two>
<three>

「空白文字がIFSの値にある限り、空白文字、スペース、タブ、改行のシーケンスは単語の先頭と末尾で無視されます」
ジェフシャラー

@JeffSchaller素晴らしいアイデア:そのセクションを追加しました。
John1024


いくつかの欠損値を持つタブ区切りファイルがある場合はどうなりますか?つまり、タブのシーケンスを単一のタブとして扱いたくない場合。また、フィールドにはコンマが含まれているため、区切り文字として使用できません。タブではなく他の区切り文字を使用する唯一のソリューションですか?
ダボス

@Davos単一のタブで区切られた各フィールドを持つデータの場合awk-F'\t'オプションまたはのように、これを簡単に処理する他のツールを使用する方が自然かもしれませんcut。または、の最新バージョンをbash使用readarrayしている-d$'\t'場合は、オプションを使用してフィールドを解析できる場合があります。
John1024
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.