之前偶然看到字段分隔符的用法,就简单拿来使用了,今天看到《Linux命令行与shell脚本编程大全》这本书时,发现了更细致的问题。

之前的用法

脚本实现

[root@ _26_ ~]# cat /tmp/test2.sh
#!/bin/bash

list="aa,bb,cc"

OLD_IFS=${IFS}
IFS=','
set -- ${list}

echo $1
echo $2
echo $3

IFS=${OLD_IFS} #使用完毕后应还原系统的默认字段分隔符

运行结果

[root@ _27_ ~]# bash /tmp/test2.sh
aa
bb
cc

分析

set -- ${list} 将list的值以空格断开,分别赋值给$1 $2 $3 等。。。

现存问题

想想如果我要使用换行符n作为字段分隔符呢,代码如下

[root@ _34_ ~]# cat /tmp/test3.sh
#!/bin/bash

list="aa\\bbncc
ddee"

OLD_IFS=${IFS}
IFS='\n'

set -- ${list}
IFS=${OLD_IFS} #使用完毕后应还原系统的默认字段分隔符

echo "1: $1"
echo "2: $2"
echo "3: $3"

运行结果

[root@ _35_ ~]# bash /tmp/test3.sh
1: aa
2: bb
3: cc
ddee

分析

可以发现,脚本并没有把换行符作为分隔符,而是把和n这两个字符串都作为了分隔符,所以在使用需要转义的分隔符时,会有这些困扰。

扩展

经过上网搜索,发现了以下几种不同写法

IFS='\n'
IFS="\n"
IFS=$"\n"
IFS=$'\n'

脚本一次性测试上述四种写法

[root@ _42_ ~]# cat /tmp/test.sh
#!/bin/bash

list="aa\\bbncc
ddee"

echo "第一种写法 ------------ IFS='\\n'"
OLD_IFS=$IFS
IFS='\n'

for i in $list;do
  echo $i
done

OLD_IFS=${IFS}

echo "第二种写法 ------------ IFS=\"\\n\""
OLD_IFS=$IFS
IFS="\n"

for i in $list;do
  echo $i
done

OLD_IFS=${IFS}

echo "第三种写法 ------------ IFS=$\"\\n\""
OLD_IFS=$IFS
IFS=$"\n"

for i in $list;do
  echo $i
done

OLD_IFS=${IFS}

echo "第四种写法 ------------ IFS=$'\\n'"
OLD_IFS=$IFS
IFS=$'\n'

for i in $list;do
  echo $i
done

OLD_IFS=${IFS}

运行结果

第一种写法 ------------ IFS='\n'
aa
bb
cc
ddee
第二种写法 ------------ IFS="\n"
aa
bb
cc
ddee
第三种写法 ------------ IFS=$"\n"
aa
bb
cc
ddee
第四种写法 ------------ IFS=$'\n'
aa\bbncc
ddee

分析

可以看到,在使用转义分隔符时,类似下面这种写法才正确

IFS=$'n'

总结

  • IFS字段分割符在分隔符为单个字符不需要转义的情况下使用方法
IFS=$';' #推荐使用
IFS=';'
IFS=; #不推荐
  • 在多个分割符且不需要转义的情况下
IFS=$',;' #推荐使用
IFS=',;'
  • 在需要转义的分隔符情况下
IFS=$'\n' #只能使用$''这种格式
IFS=$'\n,;' #只能使用$''这种格式
  • 推荐所有情况都使用统一格式
    IFS=$'分隔符字符串'
最后修改:2019 年 06 月 14 日 02 : 50 PM