在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的用法和作用,如下:
#! /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-----------------------------"
运行这个脚本结果如下:
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中执行的。