shell中的IFS变量与词分割

引入

在 bash、zsh、csh 等等各种 shell 实现中,都有一个特殊的内置变量 IFS(Internal Field Separator),意为内部字段分隔符。IFS变量值是一个字符序列,shell会将IFS字符序列中的各个字符视为 词分割(word splitting) 过程中分隔不同token的边界。

正文

1. 什么是词分割以及什么情况下会进行词分割

首先,先看一个 “魔法” 来引出我们的话题:
在这里插入图片描述
好奇怪,明明我们nums变量中数字间隔是凌乱的,为啥 echo 命令输出之后又变得整整齐齐?莫非是 echo 可以自动排版?echo 当然没有智能这种地步,这里的原因是 shell 在 nums 变量展开时 “偷偷地” 进行了词分割,把原本完整的字符串,分成了 ‘1’, ‘2’, ‘3’, ‘4’, ‘5’ 五个子字符串(token)。echo同时打印五个参数,并会默认在不同参数间添加单个空格输出,这样就有了最终整齐的输出效果。

那我们怎么把 nums 原来的模样打印出来,防止被偷偷整容呢?通过显式地添加引号即可禁止词分割
在这里插入图片描述
为了让显示的效果更明显,我在第二条命令中通过转义的方式在两侧添加了两个字面的双引号,如果觉得有些眼花缭乱,那么只看第一条就好了。

在 shell 中,命令的运行结果常以字符串类型返回,此时 shell 自动的将这个结果字符串根据规定好的分隔符切分成多个不同的子字符串(token),这一过程就是词分割。词分割会在参数展开命令替换算术展开以及读取输入的过程中发生。这里所谓 “规定好的分隔符” 即IFS变量中所包含的字符,IFS值默认为一个空格、一个制表符和一个换行符,因此默认情况下以 [ \t\n]+ 作为词分割的分隔符。同时,词分割时会忽略掉字符串开头和结尾的分隔符。

2. 自定义分隔符

除了默认的以空白符作为分隔符之外,我们也可以通过给 IFS 重新赋值修改词分割的分隔符。为更好地展示效果,定义如下函数:

function report_n_args {
	echo "$# args:"
	for arg in "$@"
	do
		echo -n "'$arg' "
	done
	echo
}

2.1 参数展开(zsh默认在参数展开时不做词分割)

在这里插入图片描述
需要注意的是,当空白符作为分隔符时,连续的空白符视作一个分隔符;当非空白字符作为分隔符时,此时连续的非空白分隔符会被作为多个分隔符。
在这里插入图片描述

2.2 命令替换

在这里插入图片描述

2.3 读取输入

如果修改了 IFS 变量值,可以简单地通过 unset IFS 恢复其默认值。
在这里插入图片描述

结语

水平有限,如文中有不恰当的地方,还请指正~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值