【问题标题】:POSIX/Bash pad variable with trailing newlines带有尾随换行符的 POSIX/Bash pad 变量
【发布时间】:2021-01-10 08:27:16
【问题描述】:

我有一个变量,里面有一些行,我想用另一个变量中定义的一些换行符来填充它。然而,似乎子shell 可能正在剥离尾随的换行符。我不能只将 '\n' 与 echo -e 一起使用,因为这些行可能已经包含需要按原样打印的转义字符。

我发现我可以使用它打印任意数量的换行符。

n=5
yes '' | sed -n "1,${n}p;${n}q"

但如果我在子shell 中运行它以将其存储在变量中,子shell 似乎会去除尾随的换行符。

我可以近似该功能,但它很笨拙,并且由于我使用它的方式,我宁愿只调用 echo "$var" 甚至使用 $var 本身来处理字符串连接之类的事情。一旦变量的最后(填充)行被删除,这个近似值就会在子shell中遇到同样的问题。

这是我的近似值

n=5
var="test"
#I could also just set n=6
cmd="1,$((n+1))p;$((n+1))q"
var="$var$(yes '' | sed -n $cmd; echo .)"

#Now I can use it with
echo "$var" |  head -n -1

基本上,我需要一种将多个换行符附加到变量的好方法,然后可以使用 echo 打印。

如果可能的话,我希望保持这个 POSIX 兼容,但在这个阶段,bash 解决方案也是可以接受的。我还将它用作工具的一部分,为此我设置了一个挑战,即在保持可读性的同时最小化行数和字符数。但是一旦我有一个可行的解决方案,我就可以解决这个问题

【问题讨论】:

    标签: bash shell echo posix subshell


    【解决方案1】:

    带有$( ) 或反引号的命令替换将修剪尾随换行符。所以不要使用它们;使用 shell 的内置字符串操作:

    n=5
    var="test"
    while [ "$n" -gt 0 ]; do
        var="$var
    "
        n=$((n-1))
    done
    

    请注意,var="$var 之后(换行符之前)不得有任何内容,下一行的" 之前不得有任何内容(无缩进!)。

    【讨论】:

    • 更明显:var+=$'\n' 使用 ANSI-C Quoting
    • @glennjackman += 和 ANSI-C 引用均不在 the POSIX spec 中。 (尽管很多 shell 都支持 ANSI-C 引用——甚至连破折号!)
    【解决方案2】:

    n 换行序列:

    printf -v spaces "%*s" $n ""
    newlines=${spaces// /$'\n'}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-25
      • 2012-06-27
      • 2012-09-13
      • 1970-01-01
      • 2011-11-05
      • 2011-04-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多