【问题标题】:Bash: Using IFS to join an array into a stringBash:使用 IFS 将数组连接成字符串
【发布时间】:2014-04-03 04:22:15
【问题描述】:

谁能解释一下这里发生了什么。所有这些都在同一个 shell 中连续执行。

$ array=(a b c)
$ echo "${array[*]}"
a b c

到目前为止一切顺利。

$ IFS=/ echo "${array[*]}"
a b c

没关系,扩展发生在整行执行之前。

$ IFS=/ x="${array[*]}"
$ echo $x
a b c

同样,扩展首先发生,x 得到了那个值。

$ echo "${array[*]}"
a/b/c

${array[*]} 已更改,并且更改是永久性的。

$ x="${array[*]}"
$ echo $x
a b c

好的,这很正常,我认为 - 原始的默认 IFS 值用于扩展此赋值中的数组变量。

$ echo "${array[*]}"
a/b/c
$ 

但这对我来说完全没有意义。首先,这里没有使用默认的IFS。其次,赋值x="${array[*]}" 并没有像之前在IFS=/ x="${array[*]}" 中那样影响${array[*]} 的值。

【问题讨论】:

    标签: arrays bash ifs


    【解决方案1】:

    首先,一些非常简单的案例来解释混乱的来源。我将使用正确的引用,虽然这里不需要,因为我们将使用单个字符串进行操作。

    案例 A:一个赋值,后跟一个命令。

    $ x=y echo "$x"
    
    $ echo "$x"
    
    $ 
    

    这里发生了两件事:

    • 当后跟命令时,分配仅对该命令是本地的。这就是为什么第二个echo "$x" 返回一个空字符串的原因。
    • 首先发生参数扩展,执行分配之前。这就是为什么第一个 echo "$x" 也返回一个空字符串的原因。实际上,x=y 在这种情况下完全没有任何作用。

    案例 B:同一行上的两个作业。

    $ x=y z="$x"
    $ echo "$x"
    y
    $ echo "$z"
    y
    $ 
    

    同样的两点现在相反:

    • 这两个分配都对 shell 的其余部分有效(或直到未设置)。
    • 不会立即进行参数扩展。执行第一次赋值,并将结果用于第二次赋值。因此,对于 shell 的其余部分,xz 都设置为 y

    数组、IFS 和引用。

    当然,这些也都发挥了作用,值得向不熟悉它们的人解释。然而,对我来说,问题主要是关于作业的,一旦澄清了,其他一切就都到位了。请注意,IFS 的值应用于未引用的 $IFS 本身。所以echo $IFS 总是会返回一个空行:

    $ IFS=BOO
    $ echo $IFS
    
    $ 
    

    【讨论】:

      【解决方案2】:

      使用时:

      IFS=/ echo "${array[*]}"
      

      然后将 IFS 设置为 echo 命令的本地(虽然不被 echo 使用)

      使用时:

      IFS=/ x="${array[*]}"
      

      然后这是两个单独的变量赋值,一个用于 IFS,一个用于 x,因此 IFS 现在永久更改为 @jaypal 提到的/

      使用时:

      $ echo "${array[*]}"
      

      然后 - 引用时 - IFS 的第一个字符用作 输出 字段分隔符并扩展数组

      如果不加引号,则生成空格分隔的字段:

      $ echo ${array[*]}
      

      另外,什么时候使用:

      $ echo "${array[@]}"
      

      然后将每个数组元素扩展为一个单独的单词,因此不使用输出字段分隔符,因此它变成了一个空格..

      【讨论】:

      • 是的,我明白了!这是导致我困惑的关键区别——当后面跟着一个命令时,分配只对该命令是本地的。当有两个赋值时,它们都对 shell 的其余部分有效。结合一些引用混淆,以及 IFS 的值用于拆分未引用的 $IFS 本身的事实,它产生了一个深刻的 WTF 时刻:D
      猜你喜欢
      • 2015-08-28
      • 2012-07-10
      • 1970-01-01
      • 2021-10-05
      • 1970-01-01
      • 2018-05-08
      • 2023-04-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多