This

STR="Hello\nWorld"
echo $STR

作为输出产生

Hello\nWorld

而不是

Hello
World

我应该做什么有一个换行在字符串?

注意:此问题与echo无关。 我知道echo -e,但我正在寻找一种解决方案,允许传递一个字符串(其中包括换行符)作为参数到其他命令,没有类似的选项来解释\n的换行符。


当前回答

我不是bash专家,但这个对我来说很管用:

STR1="Hello"
STR2="World"
NEWSTR=$(cat << EOF
$STR1

$STR2
EOF
)
echo "$NEWSTR"

我发现这更容易格式化文本。

其他回答

唯一简单的替代方法是在变量中输入新行: STR = '新的美元 线的 $STR" %s " 新 行

是的,这意味着在代码中需要的地方输入Enter。

有几个新行字符的等价物。 一种常用的表示新行字符的方法。 新行字符的八进制值。 新行字符的十六进制值。

但所有这些都需要一些工具(POSIX printf)的“解释”:

    echo -e "new\nline"           ### on POSIX echo, `-e` is not required.
    printf 'new\nline'            ### Understood by POSIX printf.
    printf 'new\012line'          ### Valid in POSIX printf.
    printf 'new\x0Aline'       
    printf '%b' 'new\0012line'    ### Valid in POSIX printf.

因此,这个工具需要用new-line来构建一个字符串:

    $ STR="$(printf 'new\nline')"
    $ printf '%s' "$STR"
    new
    line

在某些shell中,序列$'是一个特殊的shell展开。 已知在ksh93, bash和zsh中工作: STR =美元“新\在线” 当然,也可能有更复杂的解决方案: $ echo '6e65770a6c696e650a' | XXD -p -r 新 行

Or

    $ echo "new line" | sed 's/ \+/\n/g'
    new
    line

我发现-e标志优雅而直接

bash$ STR="Hello\nWorld"

bash$ echo -e $STR
Hello
World

如果字符串是另一个命令的输出,我只使用引号

indexes_diff=$(git diff index.yaml)
echo "$indexes_diff"

我对这里的选择都不太满意。这对我来说很管用。

str=$(printf "%s" "first line")
str=$(printf "$str\n%s" "another line")
str=$(printf "$str\n%s" "and another line")

那些只需要换行符而不喜欢破坏缩进的多行代码的挑剔的人可以这样做:

IFS="$(printf '\nx')"
IFS="${IFS%x}"

Bash(可能还有其他shell)在命令替换之后会占用所有尾随的换行符,因此需要用非换行符结束printf字符串,然后删除它。这也可以很容易地成为一个联机程序。

IFS="$(printf '\nx')" IFS="${IFS%x}"

我知道这是两个动作而不是一个,但我的缩进和可移植性强迫症现在是和平的:)我最初开发这个是为了能够分割换行分离的输出,我最终使用了一个修改,使用\r作为结束字符。这使得换行分割甚至适用于以\r\n结尾的dos输出。 IFS = " $ (printf ' r \ n \ ')”

我根据其他答案所做的是

NEWLINE=$'\n'
my_var="__between eggs and bacon__"
echo "spam${NEWLINE}eggs${my_var}bacon${NEWLINE}knight"

# which outputs:
spam
eggs__between eggs and bacon__bacon
knight