【问题标题】:Why bash array ignores newlines? [duplicate]为什么 bash 数组会忽略换行符? [复制]
【发布时间】:2012-11-15 11:19:09
【问题描述】:

可能重复:
Printf example in bash does not create a newline

我有一个示例脚本“array-test.sh”,它将三个函数聚合到一个数组中:

[user@host ~]$ cat array-test.sh 
#!/usr/bin/env bash

function1() {
   printf '%s\n\n\n' "cat" 
}

function2() {
   printf '%s\n\n\n' "dog" 
}

function3() {
   printf '%s\n\n\n' "mouse" 
}

for function in\
    function1\
    function2\
    function3; do
    array[$((index++))]=$($function)
done

echo "${array[@]}"
[user@host ~]$ ./array-test.sh 
cat dog mouse
[user@host ~]$ 

但是,缺少换行符。是什么导致了这种行为?

【问题讨论】:

  • 我相信$() 的行为类似于反引号运算符。
  • 你为什么要发布这么复杂的代码?您可以使用echo "$(function1)" 重现该问题
  • @KarolyHorvath:因为这是问题的本质,通常是最难解决的问题。您(声称)立即看到它的事实仅证明您比 OP 更习惯 bash 的怪癖。你为什么不通过给出一个答案而不是一个有问题的评论来炫耀你的优势?
  • @Rody Oldenhuis:请注意你的举止,你刚刚发表了粗鲁的评论。我想我没有问什么特别的。在 SO,我们希望人们提出简约的示例。我认为检查var=$(function) 是很自然的,然后下一步就是直接与echo 一起使用它。
  • @KarolyHorvath:请不要感到被冒犯;我刚刚指出对您而言,这种认识是自然而然的,但对 OP 来说可能不是。他可能将一个巨大但没有功能的代码块减少到上面的行中,他认为这是最小的。事实证明,它不是。我还指出,“在这里”,我们感谢人们以实际 answers 的形式给出答案,并且仅使用 cmets 来获取有关问题的更多详细信息或澄清某些事情,而不是像这样的快速陈述你开始了。

标签: arrays bash


【解决方案1】:

另一种选择:在字符串末尾添加一个字符(此处为@)。字符串中间的换行符将保存在$( ... ) 中。然后,通过参数扩展删除字符:

#!/bin/bash
function1() {
   printf '%s\n\n\n@' "cat" 
}

function2() {
   printf '%s\n\n\n@' "dog" 
}

function3() {
   printf '%s\n\n\n@' "mouse" 
}

for function in\
    function1\
    function2\
    function3; do
    array[index++]=$($function)
    array[index]=${array[index]%@}
done

echo "${array[@]}"

【讨论】:

    【解决方案2】:

    正如 ÁlvaroG.Vicario 所指出的,反引号(和 $())删除尾随的换行符。没有逃避它,所以如果你必须,你将不得不解决它:

    #!/usr/bin/env bash    
    
    function1() {
       printf '%s' "cat"
    }
    
    function2() {
       printf '%s' "dog"
    }
    
    function3() {
       printf '%s' "mouse"
    }
    
    for function in\
        function1\
        function2\
        function3; do
        array[$((index++))]=$($function)
    done
    
    # manually add three newlines here
    array=("${array[@]/%/$'\n'$'\n'$'\n'}")
    
    echo "${array[@]}"
    

    【讨论】:

    • 感谢您的回复!你能解释一下这种技术是如何被调用的:"${array[@]/%/$'\n'$'\n'$'\n'}"?这是数组的参数扩展吗?
    • @Martin - $'\n' => 0x0a 字符; '\n' => \n 个字符。这是一种将转义序列插入为文字字符串的方法。
    • 这应该是“模式替换”。用法是${parameter/pattern/string}。如果 是“%”,那么 被拖到 的末尾,我是否正确?
    • @Martin:是的。来自man bash(模式替换):“[...] 如果模式以 % 开头,它必须匹配参数 [...] 扩展值的末尾。”
    • @Rody:谢谢!但是,为什么第二个和第三个数组项前面有空格字符?我的意思是在输出中,“狗”和“鼠标”前面有一个空格字符。有办法避免吗?
    【解决方案3】:

    似乎 subshel​​l 扩展会削减换行符,但前提是它们出现在末尾。这是一个杂牌:

    function3() {
       printf '%s\n\n\n-' "mouse" 
    }
    
    foo=$(function3)
    foo=${foo%-}
    echo "$foo"
    

    【讨论】:

    • 这很聪明 :) 但是,出于某种原因,“狗”和“鼠标”前面仍然有一个空格字符。
    • 您需要将'-' 字符添加到每个函数中输出字符串的末尾。但它可以是任何字符,只要您在 ${foo%HERE} 中有它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-22
    • 2015-11-13
    • 2013-11-15
    • 1970-01-01
    • 2020-11-15
    • 2021-08-21
    • 1970-01-01
    相关资源
    最近更新 更多