为单个语句设置 IFS
Setting IFS for a single statement
在我的 GNU bash, version 4.3.42(1)-release
上,我正在对 做一些测试。这个想法是将一个 :
分隔的字符串及其每个元素拆分成一个数组。
为此,我尝试在命令范围内将 IFS
设置为 :
,以便自动拆分并且 IFS
保持不变:
$ myvar="a:b:c"
$ IFS=: d=($myvar)
$ printf "%s\n" ${d[@]}
a
b
c
显然 IFS
保持不变:
$ echo $IFS
# empty
If IFS is unset, the parameters are separated by spaces. If IFS is
null, the parameters are joined without intervening separators.
但是,然后我注意到 IFS
有点坏了,所以 echo $myvar
returns a b c
而不是 a:b:c
.
取消设置值解决了它:
$ unset IFS
$ echo $myvar
a:b:c
但我想知道:这是什么原因造成的? IFS=: command
改变 IFS
不只是在正在执行的命令范围内吗?
我在 Setting IFS for a single statement 中看到这确实有效:
$ IFS=: eval 'd=($myvar)'
$ echo $myvar
a:b:c
但我不明白为什么会这样,IFS=: d=($myvar)
不明白。
IFS
在同一行与 read
表现良好:
myvar="a:b:c"
IFS=: read -ra d <<< "$myvar"
printf "%s\n" "${d[@]}"
a
b
c
检查 IFS
的值:
declare -p IFS
-bash: declare: IFS: not found
很明显 IFS
在当前 shell 中没有被篡改。
现在检查原始输入:
echo $myvar
a:b:c
或:
echo "$myvar"
a:b:c
看到你用的时候我就想评论一下,刚才才想起来是什么问题。行
IFS=: d=($myvar)
暂不设置IFS
;它只是在当前 shell 中设置两个变量。 (简单命令可以以本地环境设置为前缀,但赋值语句本身不是简单命令。)
写的时候
echo $IFS
IFS
扩展为:
,但是因为:
是IFS
的第一个字符,所以在分词的时候去掉了。使用
echo "$IFS"
将显示 IFS
仍设置为 :
。
在bash中,您可以设置一个变量,该变量仅当该语句本身不是变量赋值时才对单个语句有效。例如:
$ foo=one bar=two
$ echo $foo
one
要使第二个赋值成为语句的一部分,您需要...一些其他语句。正如您所注意到的,eval
有效。此外,read
应该有效:
$ foo="one:two:three"
$ IFS=: read -r -a bar <<< "$foo"
$ declare -p bar
declare -a bar='([0]="one" [1]="two" [2]="three")'
在我的 GNU bash, version 4.3.42(1)-release
上,我正在对 :
分隔的字符串及其每个元素拆分成一个数组。
为此,我尝试在命令范围内将 IFS
设置为 :
,以便自动拆分并且 IFS
保持不变:
$ myvar="a:b:c"
$ IFS=: d=($myvar)
$ printf "%s\n" ${d[@]}
a
b
c
显然 IFS
保持不变:
$ echo $IFS # empty
If IFS is unset, the parameters are separated by spaces. If IFS is null, the parameters are joined without intervening separators.
但是,然后我注意到 IFS
有点坏了,所以 echo $myvar
returns a b c
而不是 a:b:c
.
取消设置值解决了它:
$ unset IFS
$ echo $myvar
a:b:c
但我想知道:这是什么原因造成的? IFS=: command
改变 IFS
不只是在正在执行的命令范围内吗?
我在 Setting IFS for a single statement 中看到这确实有效:
$ IFS=: eval 'd=($myvar)'
$ echo $myvar
a:b:c
但我不明白为什么会这样,IFS=: d=($myvar)
不明白。
IFS
在同一行与 read
表现良好:
myvar="a:b:c"
IFS=: read -ra d <<< "$myvar"
printf "%s\n" "${d[@]}"
a
b
c
检查 IFS
的值:
declare -p IFS
-bash: declare: IFS: not found
很明显 IFS
在当前 shell 中没有被篡改。
现在检查原始输入:
echo $myvar
a:b:c
或:
echo "$myvar"
a:b:c
看到你用的时候我就想评论一下,刚才才想起来是什么问题。行
IFS=: d=($myvar)
暂不设置IFS
;它只是在当前 shell 中设置两个变量。 (简单命令可以以本地环境设置为前缀,但赋值语句本身不是简单命令。)
写的时候
echo $IFS
IFS
扩展为:
,但是因为:
是IFS
的第一个字符,所以在分词的时候去掉了。使用
echo "$IFS"
将显示 IFS
仍设置为 :
。
在bash中,您可以设置一个变量,该变量仅当该语句本身不是变量赋值时才对单个语句有效。例如:
$ foo=one bar=two
$ echo $foo
one
要使第二个赋值成为语句的一部分,您需要...一些其他语句。正如您所注意到的,eval
有效。此外,read
应该有效:
$ foo="one:two:three"
$ IFS=: read -r -a bar <<< "$foo"
$ declare -p bar
declare -a bar='([0]="one" [1]="two" [2]="three")'