当我将IFS
变量设置为空格时,bash
将多个空格视为一个空格(myprogram
是一个打印它收到的命令行参数的程序):
IFS=" "
x="hello hi world"
./myprogram $x
argv[1] = hello
argv[2] = hi
argv[3] = world
但是当我将IFS
变量设置为逗号时,bash
不会将多个逗号视为一个逗号:
IFS=","
x="hello,,,hi,,,world"
./myprogram $x
argv[1] = hello
argv[2] =
argv[3] =
argv[4] = hi
argv[5] =
argv[6] =
argv[7] = world
这是为什么?
答案1
这记录在man bash
. IFS 中任何非空白字符的一次出现都会界定字段。
从man bash
:
shell 将 IFS 的每个字符视为分隔符,并使用这些字符作为字段终止符将其他扩展的结果拆分为单词。如果 IFS 未设置,或其值恰好为
<space><tab><newline>
默认值,则忽略先前扩展结果的开头和结尾处的<space>
、<tab>
、 和序列,并且不在开头或结尾处的任何 IFS 字符序列用于分隔<newline>
字。如果 IFS 的值不是默认值,则单词开头和结尾处的空格、制表符和换行符序列将被忽略,只要该空格字符在 IFS 的值中(IFS 空格字符)。 IFS 中非 IFS 空白的任何字符以及任何相邻的 IFS 空白字符共同界定字段。 IFS 空白字符序列也被视为分隔符。 如果IFS的值为空,则不会发生分词。 [强调。]
示例:字段分割
如果 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>