为何Shell中将IFS设置为'\n'时,普通字母n也会被当作IFS分隔符?
原因解析
IFS=\n没有将IFS设置为换行符,本质是对Shell转义规则的误用:
- 无引号包裹的Shell语句中,反斜杠
\仅对紧随其后的Shell特殊元字符(空格、$、&、命令分隔符、换行符等)生效,作用是取消对应字符的特殊语义;如果反斜杠后接的是普通字符(例如字母n),反斜杠会被Shell直接丢弃,仅保留后续的普通字符本身。 - 因此
IFS=\n的实际执行效果等价于IFS=n,IFS的值为单个字母n,所有出现字母n的位置都会被识别为分隔点。你看到的输出里programming被切为programmi和g,就是刚好在n的位置做了分割,和这个逻辑完全吻合。 - 你脚本第一个循环的输出是默认IFS的正常表现:默认IFS值为空白类字符(空格、制表符、换行符),所以字符串里的所有空格、换行都会触发分割,每个单词单独输出一行。
正确设置IFS为换行符的方式
不要直接写IFS=\n,使用以下任意一种正确写法即可:
- 最通用的ANSI-C引用写法,兼容性最好:
IFS=$'\n'
$'...'是Shell原生支持的ANSI-C引用结构,会正确将\n解析为ASCII换行符。
- 直接嵌入字面换行(可读性较差,不推荐):
IFS=' '
写法为单引号包裹后直接敲入回车,单引号内的换行会被原样保留为IFS的值。
- 通过printf生成换行赋值:
IFS=$(printf '\n')
效果和第一种写法一致,写法相对繁琐。
将脚本中错误的IFS=\n替换为IFS=$'\n'后,第二个循环就会按换行做分割,正常输出三行完整的编程语言条目,不会再把字母n识别成分隔符。
内容的提问来源于stack exchange,提问作者ᄑᄀᄀᄉ
相关产品推荐
相关产品推荐

