This
STR="Hello\nWorld"
echo $STR
作为输出产生
Hello\nWorld
而不是
Hello
World
我应该做什么有一个换行在字符串?
注意:此问题与echo无关。 我知道echo -e,但我正在寻找一种解决方案,允许传递一个字符串(其中包括换行符)作为参数到其他命令,没有类似的选项来解释\n的换行符。
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=$(printf "%s" "first line")
str=$(printf "$str\n%s" "another line")
str=$(printf "$str\n%s" "and another line")
如果你正在使用Bash,你可以在一个特别引用的$'string'中使用反斜杠转义。例如,添加\n:
STR=$'Hello\nWorld'
echo "$STR" # quotes are required here!
打印:
Hello
World
如果你使用的是其他shell,只需在字符串中插入换行符:
STR='Hello
World'
Bash在$ "字符串中识别出许多其他反斜杠转义序列。以下是Bash手册页面的节选:
Words of the form $'string' are treated specially. The word expands to
string, with backslash-escaped characters replaced as specified by the
ANSI C standard. Backslash escape sequences, if present, are decoded
as follows:
\a alert (bell)
\b backspace
\e
\E an escape character
\f form feed
\n new line
\r carriage return
\t horizontal tab
\v vertical tab
\\ backslash
\' single quote
\" double quote
\nnn the eight-bit character whose value is the octal value
nnn (one to three digits)
\xHH the eight-bit character whose value is the hexadecimal
value HH (one or two hex digits)
\cx a control-x character
The expanded result is single-quoted, as if the dollar sign had not
been present.
A double-quoted string preceded by a dollar sign ($"string") will cause
the string to be translated according to the current locale. If the
current locale is C or POSIX, the dollar sign is ignored. If the
string is translated and replaced, the replacement is double-quoted.
问题不在于外壳。问题实际上出在echo命令本身,以及变量插值时缺少双引号。您可以尝试使用echo -e,但并非所有平台都支持它,这也是现在推荐使用printf的原因之一,因为它具有可移植性。
您还可以尝试直接在shell脚本中插入换行符(如果您正在编写脚本),因此它看起来像…
#!/bin/sh
echo "Hello
World"
#EOF
或者同样的
#!/bin/sh
string="Hello
World"
echo "$string" # note double quotes!
在我的系统(Ubuntu 17.10)上,你的例子就像预期的那样工作,无论是从命令行输入(到sh)还是作为sh脚本执行:
[bash]§ sh
$ STR="Hello\nWorld"
$ echo $STR
Hello
World
$ exit
[bash]§ echo "STR=\"Hello\nWorld\"
> echo \$STR" > test-str.sh
[bash]§ cat test-str.sh
STR="Hello\nWorld"
echo $STR
[bash]§ sh test-str.sh
Hello
World
我想这回答了你的问题:它就是有效。(我没有试图弄清楚诸如在sh中换行符替换\n的具体时间)。
然而,我注意到这个脚本在使用bash执行时会表现不同,而是会打印出Hello\nWorld:
[bash]§ bash test-str.sh
Hello\nWorld
我已经设法获得所需的输出与bash如下:
[bash]§ STR="Hello
> World"
[bash]§ echo "$STR"
注意$STR周围的双引号。如果保存并作为bash脚本运行,则行为相同。
下面也给出了期望的输出:
[bash]§ echo "Hello
> World"
那些只需要换行符而不喜欢破坏缩进的多行代码的挑剔的人可以这样做:
IFS="$(printf '\nx')"
IFS="${IFS%x}"
Bash(可能还有其他shell)在命令替换之后会占用所有尾随的换行符,因此需要用非换行符结束printf字符串,然后删除它。这也可以很容易地成为一个联机程序。
IFS="$(printf '\nx')" IFS="${IFS%x}"
我知道这是两个动作而不是一个,但我的缩进和可移植性强迫症现在是和平的:)我最初开发这个是为了能够分割换行分离的输出,我最终使用了一个修改,使用\r作为结束字符。这使得换行分割甚至适用于以\r\n结尾的dos输出。 IFS = " $ (printf ' r \ n \ ')”