使用echo时如何添加新行


42

为什么以下命令没有在生成的文件中插入换行符,该怎么办?

$ echo "Line 1\r\nLine2" >> readme.txt

$ cat readme.txt 
Line 1\r\nLine2

6
echo强制性的吗?您可以使用printf
Archemar

我不了解printf,它可以和printf一起工作:P ...那么,什么使它不能与echo一起工作呢?
塞德·亚兹达尼

\r包含在输出中还是CRLF换行的一部分?
cuonglm

9
echo命令的许多不同实现彼此不兼容。因此,建议使用更多标准工具作为printf。有关问题的扩展概述,请参见unix.stackexchange.com/questions/65803/…
jimmij 2015年

Answers:


38

echo


echo,如果你做这严格遵循统一UNIX规范的实施将增加新行:

echo 'line1\nline2'

但这不是可靠的行为。实际上,实际上没有您可以期望的任何标准行为echo

经营者

string

要写入标准输出的字符串。如果第一个操作数为-n,或者任何操作数包含< \反斜杠>字符,则结果是实现定义的

符合XSI的系统上,如果第一个操作数为-n,则应将其视为字符串,而不是option。在任何自变量中,在符合XSI的系统上应识别以下字符序列:

\a-编写<alert>

\b-编写<backspace>

\c-禁止<newline>,否则该<newline>将跟随输出中的最终参数。\c参数后面的所有字符都将被忽略。

\f-编写<form-feed>

\n-编写<newline>

\r-编写<carriage-return>

\t-编写<tab>

\v-编写<vertical-tab>

\\-写一个<反斜杠>字符。

\0num-写入一个8位值,该值是零,一,二或三位八进制数num

因此,实际上没有任何通用的方法可以知道如何使用编写换行符echo,只是您通常只能依靠这样echo做。

一个bash外壳通常不会符合规范,并处理-n和其他选项,但即使是不确定的。你可以做:

shopt -s xpg_echo
echo hey\\nthere

hey
there

如果已经使用build-time选项进行了构建,那么甚至没有必要bash...

--enable-xpg-echo-default

echo默认情况下,使该内置扩展反斜杠转义字符,而不需要该-e选项。这会将xpg_echoshell选项的默认值设置为on,这使Bash的echo行为更像Single Unix Specification版本3中指定的版本。有关可识别的转义序列的说明,请参见Bash Builtinsecho


printf


另一方面,printf相比较而言,的行为相当温和。

理据

printf添加了该实用程序以提供历史上由所提供的功能echo。但是,由于现存的各个版本之间存在无法协调的差异,因此echo该版本具有一些特殊功能,而这些功能则留给了printf基于第九版系统中的一个的新实用程序。

扩展说明部分几乎完全符合printf()ISO C标准中的功能,尽管它是根据XBD文件格式符号中的文件格式符号描述的

它处理描述其参数的格式字符串-可以是任意数量的东西,但是对于字符串来说,要么是%byte字符串,要么是字面%s量。除了%f第一个参数中的%bormats之外,它的行为最像yte字符串参数,只是它不处理\c转义符。

printf ^%b%s$ '\n' '\n' '\t' '\t'

^
\n$^    \t$

看到为什么printfecho什么更好?更多。


echo() printf


您可能会写自己的符合标准的文件,echo例如...

echo(){
    printf '%b ' "$@\n\c"
}

...应该几乎总是自动执行正确的操作。

实际上,不... \n如果最后一个参数以奇数个<backslashes>结尾,则会在参数的末尾打印一个文字。

但这不是:

echo()
    case    ${IFS- } in
    (\ *)   printf  %b\\n "$*";;
    (*)     IFS=\ $IFS
            printf  %b\\n "$*"
            IFS=${IFS#?}
    esac

+1为默认使用的shopt -s xpg_echo选项。echo-e
Vignesh Raja

没有,此解决方案将无法工作-e。我很惊讶没有人注意到,除了@HaydeSchiff
ha9u63ar

@ ha9u63ar-呃...你读过这个吗?
mikeserv

27

传递-e标志以回显以使其解析转义的字符,例如“ \ r \ n”,如下所示:

echo -e "Line 1\r\nLine2" >> readme.txt

一个不错的简单的“ -e”选项使转义序列起作用-它在另一个答案中说这echo是不可靠的,并且不遵循printf
爱德华

1
确保您的脚本不包含任何文字\ r \ n,例如在tr -d "\n"命令中。
Noumenon

8

在我使用过的bash的所有版本中,您可以简单地以交互方式或在脚本中将文字换行符插入字符串中,前提是该字符串具有足够的引号。

互动地:

$ echo "Line one
> Line two"
Line one
Line two
$

在脚本中:

echo "Line one
Line two"

4
echo -e "Line 1\r\nLine2" >> readme.txt

进一步的使用可能性:

man echo

2

人们已经做出了充分的回答,但是我拒绝接受echo接受除以外的任何选择的世界-n

nl='
'
echo Line 1"$nl"Line 2"$nl"Line 3

1

如果您的字符不属于消息,则可以通过sed传递消息

$ echo "Time on the next line:@$(date +"%Y-%m-%dT%T%z")" | sed -e's/@/\n/g'
Time on the next line:
2016-03-25T10:12:39-0500
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.