shell编程(十四)IFS深入探究

一    IFS

①  IFS变量的定义

man -Len -Pcol\ -b bash | sed -ne '/^ *IFS /{N;N;p;q}'

1)字符串'扩展'之后,用来'做单词分割'

2)内建的'read'命令,利用'IFS-->换行符'将文件'每行'内容作为一个'大单词'

②  字符分割中使用IFS

1)Shell把变量'IFS内'的'每一个字符'都当做是'一个分割符'(delimeter),用这些字符作为'每一个字段(word)'的结束符来进行分割

2)如果IFS'没有设置(unset)'或者IFS的值被设置为" \t\n"默认值(space, tab和 newline),那么操作对象的'开始'和'结束处'的所有space, tab和newline序列都'将被忽略',但是操作对象'中间'的space, tab和newline序列会'作为界定符'工作

3)如果IFS值'不是默认值'(程序中对IFS'重新'设置过),只有'出现在IFS内的空白字符'(可能是space, tab或newline中的一个或几个)才会在单词'开始和结束'处被忽略,这里'说的是单词',而'不是整个'操作对象

4)IFS内的'非空白字符'多个'连续出现'时,'每个'非空白字符会被当做'单独的分隔符'看待

5)如果IFS为空("null"),则'不会进行'单词分割

1)解读一

IFS中的'空格'、','、'.'字符都被当作'单词'分割符

备注: 如果以默认的'IFS'分割,',.'也会被当作单词的'一部份'

2)解读二

说明:1个空格、2个空格、3个空格、'1个制表符'、5个空格、6个空格

3)解读三

1)vim中'默认'的'tab'是8个'空格',但是区别于8个空格,表示'一个字符'

+++++++++++'设置Tab键缩进为4个字符'+++++++++++

vim ~/vimrc

set tabstop=4

思考: vimrc中配置是否影响'IFS'的判断?

备注: 这里'测试时'暂时不重新配置'tabstop'

4)解读四

IFS讨论帖

1)用'新的IFS-->B'来分割字符串"aBcBBdBBBeBBBB",显然前面"a"、"b"、"c"、"d"都被分割为'单独'的字符串了

2)从'输出'可见,中间还有'若干个空字符串-->null'

3)这个'空串'就是'IFS'之间分割得到的

4)即使'多个(非空白)分隔符'挨在一起,仍然是'按照单个分隔符'进行分割

'非'空白字符做'IFS'时,如果'不连续'则正常作为'界定符';如果连续,则连续的'非IFS'都由'空格'替代

换句话说: n个'(n>=2)'的'非IFS'字符会由'n'个'空格'代替

注意: 区分多个连续的'IFS空白字符'和'IFS非空白字符的区别'

说明: 从'输出'的情况来看,按照'B',分割除了'14'个所谓的'单词' -->测试:'number计数'

5)解读五

IFS='','不会'做任何分割,所以'作为一个整体'输出

效果等价: "${var}"

③  特殊参数使用IFS

++++++++++'IFS对'变量$*的'扩展'的影响++++++++++:

1)当用双引号("double quotes")来'引用特殊变量'$*时,会使用'IFS变量的第"1个"字符'来连接$*参数的每一个部分,即"$*"相当于"$1c$2c...",其中c是IFS变量的'第一个'字符

2)如果'没有设置'IFS,则c为空格字符(space),实际上默认情况下IFS变量的'第1个字符就是空格字符'

3)如果'IFS为空'(null),则"$*"内各参数会'直接连接'在一起

1)$*带不带双引号的区别 

2)$@带不带双引号的区别

'上面例子'说明: 不管'带不带'双引号,'IFS'无法影响'$@'

注意: 如果脚本'传参'过程,'参数中有空格',要用'引号(单双皆可)括起来'声明是一个整体;如果参数中'有变量',必须加'双引号'
​
++++++++'$@带双引号与不带双引号区别'++++++++

脚本传参: 变量'本身带有'空格

小结: "$@" 永远是分割成 "$1"、"$2"、"$3"独立的部分

不管变量值是否有'空格',只要是参数带有"",都会作为'一个'完整的'位置参数'

++++++++++'继续探讨一个细节'++++++++++

变量'不加双引号'呢?

是把'$hello'作为一个参数;还是$hello'拆解后'才作为参数

④  数组引用中使用IFS

关键点: ${name[*]}被'包含在双引号'内,则其将会用'IFS的第1个字符连接'数组的各个元素进行扩展,跟上面使用'双引号引用特殊参数$*'一样

说明: 关'于数组的使用'会开一个'专题'

⑤  思考1

已知: 我们知道,通常'位置参数'以'空白字符'作为分割符进行分割

思考: 我们是否在'参数传递'时候,修改'位置参数分隔符',使用'其它符'号进行分割,例如':,甚至字母'

说明: 这里尝试用','作为分割符

备注: 该'分割符号'最好不要有'特殊'的含义,被'shell'转义了

+++++++++++++'结论'+++++++++++++

1. IFS 除了对"参数扩展"有作用-->具体'就是'加"双引号"的"$*" 

备注: $* 是 $1 - $n, '不包括 $0'

2. IFS 还对'参数位置'有作用,参数位置由'IFS'、及有无" "(作为整体) 决定

备注: 默认'IFS就是空白字符',非特殊情况'不建议'修改

⑥  思考2

已知: 我们知道'子shell'是可以'继承父shell'的环境变量的

问题: 我们在父shell命令行'非export'修改'IFS'值,子shell继承的是修改'前'的还是修改'后'的

后续测试: 脚本中'调用子脚本'

结论: '父shell'修改IFS,不会影响'子shell';如果想修改'IFS',只能在'子shell'中修改,'无法'通过继承的方式

+++++++++++'其它变量呢'+++++++++++

⑦  read命令

⑧  IFS修改恢复

场景: 我们只想'临时修改',让其在'特定的时刻'工作

+++++++++++'三种方式'+++++++++++

方式1: 使用一个'中间变量'保存原始值,然后'修改IFS',操作'完成后'再使用中间变量'恢复'IFS

方式2: 使用'local(函数中)来声明'要使用的IFS变量来'覆盖'全局变量,由于local变量只在'局部有效',所以操作完'不需要恢复'IFS

备注: 建议使用$'string'的方式进行'还原'-->'成功'使用反斜杠转义 -->IFS=$' \t\n'

补充: 之'前'的方式是IFS_BAK="$IFS"

小结

二  参考博客

详细解析Shell中的IFS变量

Shell中的IFS解惑

IFS简单说明

将数组份分割成字符串

其它参考

其它参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值