在此示例中如何使用IFS

  • 本文关键字:何使用 IFS bash ifs
  • 更新时间 :
  • 英文 :


我正在阅读有关bash内部变量的阅读,并遇到了此IFS示例:

output_args_one_per_line()
{
  for arg
  do
    echo "[$arg]"
  done #  ^    ^   Embed within brackets, for your viewing pleasure.
}

case1

IFS=" "
var=" a  b c   "
output_args_one_per_line $var
#OUTPUT
# [a]
# [b]
# [c]

case2

IFS=:
var=":a::b:c:::"               # Same pattern as above
CASE2   
                        # but substituting ":" for " "  ...
output_args_one_per_line $var
# []
# [a]
# []
# [b]
# [c]
# []
# []

现在,根据我的理解, IFS的值是否为默认的 tn,而不是删除领先和尾随的范围。因此,对于case1 bash,将 var视为 a b c,因此输出。

对于我说,根据我的看法,bash将 var视为 |a||b|c|||在此处将 |视为 space。我使用

检查了它
Noob@Noob:~/tmp$ IFS=$':' FOO=$":a::b:c:::"; echo $FOO $'x'
 a  b c   x

所以,我对案例2的预期输出是

# []
# [a]
# []
# []
# [b]
# [c]
# []
# []
# []

所以,有人可以在内部向我解释Bash在情况2中如何治疗var,而我在哪里误会了我的理解。

您的主张(编辑为使用':'而不是'|'):

对于我的case2,根据我的bash bash看到var as:a :: b:b:c ::: treat:在这里空间。

是错误的。IFS导致bash:视为单词分离器,而不是空格。不要仅仅因为空格是默认 word saparator。

on 案例2 您的":a::b:c:::"带有IFS=:
因此,您正在做的是在每个MET :

中拆分字符串

因此,从字符串的开头,直到第一个:您有":
这是 nothing ,因此[]

从第一个:到下一个:您有:a:
a,因此[a]

从那里到下一个:您有::
这是 nothing ,因此[]

从那里到下一个:您有:b:
b,因此[b]

从那里到下一个:您有:c:
c,因此[c]

从那里到下一个:您有::
这是 nothing ,因此[]

从那里到下一个:您有::"
这是 nothing ,因此[]

所以你得到了结果。


如@mark Reed,您可以使用printf
bash -x一起,您可以得到:

$ bash -x
$ IFS=':'; var=':a::b:c:::'; printf "[%s]n" $var
[12]+ IFS=:
[12]+ var=:a::b:c:::
[12]+ printf '[%s]n' '' a '' b c '' ''     # notice this
[]
[a]
[]
[b]
[c]
[]
[]

:是定界符。a:b分为ab,两者之间没有。在您的预期行为中,您将如何编码以下内容?

[a]
[]
[b]

唯一奇怪的是,最后没有三个空字符串。这可能是因为

未引用的隐式null参数,是由于没有值的参数的扩展而产生的。

原因很简单:

IFS=" "
var=" a  b c   "
output_args_one_per_line $var

这意味着使用此参数调用output_args_one_per_line

output_args_one_per_line  a  b c   

解析命令行时,bash将删除额外的空白,因此实际呼叫将使用

output_args_one_per_line a b c

即。多个空间合并为一个,a之前的空间将成为命令和第一个参数之间的空间。

这意味着在应用 IFS之前,空间将消失。这也意味着您不能写

IFS=:
output_args_one_per_line:$var

命令后必须有一个空白,而不是单词分离器。

您可以使用set -x运行脚本以查看跟踪输出(即Bash如何展开行)。

在第二种情况下,定界符一词不是空间字符,因此命令和第一个参数之间的必要空格与参数没有合并,该行变为

output_args_one_per_line :a::b:c:::

唯一奇怪的是,输出应该是c之后的三个空参数,但这可能是因为删除了空的尾随参数(就像Bash在参数后删除了白空间一样)。这是另一个奇怪的输出:

IFS=:
var=":a::b:c::: "   # Blank after C
> output_args_one_per_line $var
[]
[a]
[]
[b]
[c]
[]
[]
[ ]

因此,如果var在最后一个结肠后确实包含任何内容,我们会得到缺失的参数。

相关内容

  • 没有找到相关文章