在bash中IFS是内部的域分隔符,manual中对其的叙述如下:
IFS The Internal Field Separator that is used for word splitting after expansion and to split lines into words with the read builtin command. The default value is
如下是一些值得注意的地方。
1. IFS的默认值为:空白(包括:空格,tab, 和新行),将其ASSII码用十六进制打印出来就是:20 09 0a (见下面的shell脚本)。
2. IFS对空格的空白的处理和其他字符不一样,左右两边的纯空白会被忽略,多个连续的空白被当成一个IFS处理。
3. S*中使用IFS中的第一个字符。
4. awk中的FS(域分隔符)也和IFS有类似的用法和作用。
我写了一个shell脚本来演示IFS的用法和作用,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
#! /bin/bash #author: Jay Ren #date: 2011.12.10 echo "----------------------------------IFS test--------------------------------" echo "default \$IFS is:(ASSII in hexadecimal value)" echo -n "$IFS" | xxd -g 1 | awk -F":" '{print $2}' | awk -F" " '{print $1, $2, $3}' echo "by default, IFS should be a SPACE, a HORIZONTAL TAB, or a LINC FEED." function output_args_one_per_line() { arg_list=$* echo "\$*='$*'" for arg in $arg_list do echo "[$arg]" done } echo "--------------------------------------------------------------------------" echo "set IFS=' ' #dealing with SPACE in IFS is different with other chars." echo "var=' a b c '" IFS=' ' var=" a b c " output_args_one_per_line $var echo "--------------------------------------------------------------------------" echo "set IFS=':'" echo "var='::a:b::c:::'" IFS=':' var="::a:b::c:::" output_args_one_per_line $var echo "--------------------------------------------------------------------------" echo "set IFS='+:-;' #but \$* just use 1st char in IFS as the separator." echo "var='::a:b::c:::'" IFS='+:-;' var="::a:b::c:::" output_args_one_per_line $var echo "--------------------------------------------------------------------------" echo "set IFS='-+:;' #but \$* just use 1st char in IFS as the separator." echo "var='::a:b::c:::'" IFS='-+:;' var="::a:b::c:::" output_args_one_per_line $var echo "--------------------------The END of IFS test-----------------------------" |
运行这个脚本结果如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
master@jay-linux:~/workspace/mygit/shell/sh2011$ ./IFS-test.sh ----------------------------------IFS test-------------------------------- default $IFS is:(ASSII in hexadecimal value) 20 09 0a by default, IFS should be a SPACE, a HORIZONTAL TAB, or a LINC FEED. -------------------------------------------------------------------------- set IFS=' ' #dealing with SPACE in IFS is different with other chars. var=' a b c ' $*='a b c' [a] [b] [c] -------------------------------------------------------------------------- set IFS=':' var='::a:b::c:::' $*='::a:b::c::' [] [] [a] [b] [] [c] [] -------------------------------------------------------------------------- set IFS='+:-;' #but $* just use 1st char in IFS as the separator. var='::a:b::c:::' $*='++a+b++c++' [] [] [a] [b] [] [c] [] -------------------------------------------------------------------------- set IFS='-+:;' #but $* just use 1st char in IFS as the separator. var='::a:b::c:::' $*='--a-b--c--' [] [] [a] [b] [] [c] [] --------------------------The END of IFS test----------------------------- |
var='::a:b::c:::'
$*='::a:b::c::'
为什么 $* 的值里最后一位少了一个":" ?百思不得其解……
哎呀,你火眼金睛啊,赞~~ 我当时写这个例子的时候,也发现这个问题了的,简单看了一下没能解释;然后,我有时间时会去认真看一下这个问题(估计年后了,最近太忙);如果你理解了,麻烦你也来update一下吧,互相学习
我写了一篇文章,可以参考下。http://blog.csdn.net/whuslei/article/details/7187639。欢迎指正
嗯 看了你文章明白了,谢谢~ 按照这样的规则 [变量][IFS][变量][IFS]……根据原始 var 值中所有的分割符(此处是":")划分出变量;echo $*之时,用分隔符来隔开变量,但是末尾处是不再写IFS的(因为后面没有变量了,不需要IFS来间隔了。
你这里都是作为参数处理的,如果作为变量的话当你echo "$a",带引号输出的时候,将不会替换成为新的分隔符,而只是输出,请问这是为什么呢
[root@web1 ~]# vi ifs3
function export()
{
b=$*
echo "--vars export in func"
echo "$b"
echo $b
echo "--args expport in func"
echo "$*"
echo $*
}
a="1,2,3,,"
IFS='+,'
echo "--vars export"
echo "$a"
echo $a
export $a
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
"ifs3" 21L, 206C written
[root@web1 ~]# ./ifs3
--vars export
1,2,3,,
1 2 3
--vars export in func
1+2+3+
1 2 3
--args expport in func
1+2+3+
1 2 3
[root@web1 ~]#
变量里面的字符当然不应该被IFS改变了,否则变量随意变了,那才奇怪了。
另外请教一下,你这个博客是用什么软件搭建的啊 风格很喜欢啊
wordpress加了个另外的主题风格。 后面我会准备写一下我今年升级了博客的风格等东西。
请教下,IFS=':' 时,echo "[$arg]" 的最后为什么只输出一个[]?$* 的最后部分应该有两个空字段的
请看 我第一个评论的讨论;$*是重新组装的
那个讨论看到了 明白了加双引号的$* 是怎么组成的
但是对于没有引用的$* 讨论中的链接中有提到:【 $* 和 $@ 的值都是 "" "" "a" "b" "" "c" "" "" 。可以说是一个列表……】这样遍历 $arg_list时 不是应该输出8个字符吗??
IFS退出脚本后要还原吗?会不会影响其它脚本的运行
不会影响其他脚本。不需要还原。因为是不同的shell中执行的。