Bash:cat 和 echo 的区别

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18680242/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 06:29:50  来源:igfitidea点击:

Bash: difference between cat and echo

bash

提问by Maria Ines Parnisari

This is file.txt:

这是file.txt

foo:bar:baz:qux:quux
one:two:tree:four:five:six:seven
alpha:beta:gamma:delta:epsilon:zeta:eta:teta:iota:kappa:lambda:mu
the quick brown fox jumps over the lazy dog

This is what I tried in the terminal:

这是我在终端中尝试的:

user@notebook:~/Desktop$ cat file.txt 
foo:bar:baz:qux:quux
one:two:tree:four:five:six:seven
alpha:beta:gamma:delta:epsilon:zeta:eta:teta:iota:kappa:lambda:mu
the quick brown fox jumps over the lazy dogmuser@notebook:~/Desktop$ cat read.sh 
while read -r line
do
    echo $line
done < file.txt

user@notebook:~/Desktop$ ./read.sh 
foo:bar:baz:qux:quux
one:two:tree:four:five:six:seven
alpha:beta:gamma:delta:epsilon:zeta:eta:teta:iota:kappa:lambda:mu

My question is: why doesn't read.shshow the last end of line like cat file.txtdoes?

我的问题是:为什么不像这样read.sh显示最后一行cat file.txt

采纳答案by Baiyan Huang

Because there is no end of line in file.txt, if you:

因为 file.txt 中没有行尾,如果你:

$ od -c file.txt
0000000   f   o   o   :   b   a   r   :   b   a   z   :   q   u   x   :
0000020   q   u   u   x  \n   o   n   e   :   t   w   o   :   t   r   e
0000040   e   :   f   o   u   r   :   f   i   v   e   :   s   i   x   :
0000060   s   e   v   e   n  \n   a   l   p   h   a   :   b   e   t   a
0000100   :   g   a   m   m   a   :   d   e   l   t   a   :   e   p   s
0000120   i   l   o   n   :   z   e   t   a   :   e   t   a   :   t   e
0000140   t   a   :   i   o   t   a   :   k   a   p   p   a   :   l   a
0000160   m   b   d   a   :   m   u  \n   t   h   e       q   u   i   c
0000200   k       b   r   o   w   n       f   o   x       j   u   m   p
0000220   s       o   v   e   r       t   h   e       l   a   z   y    
0000240   d   o   g

There are no \nat the end of the file.

\n文件末尾没有。

echoon the other other hand will always add a new line when you echo a message if there isn't one.

echo另一方面,如果没有消息,当您回显消息时,总是会添加一个新行。

回答by Aleks-Daniel Jakimenko-A.

Other answers are right, there is simply no newline character in the end of your file.txt.

其他答案是正确的,在您的file.txt.

Most text editors will end a file with a newline automatically, even nanodoes that. But your file was generated by a script, right? To reproduce this behavior all you have to do is:

大多数文本编辑器会自动以换行符结束文件,即使nano这样做也是如此。但是你的文件是由脚本生成的,对吗?要重现此行为,您只需:

echo -n 'hello world' >> file.txt

-nflag tells echo not to output the trailing newline.

-n标志告诉 echo 不要输出尾随的换行符。

Also, if you want your readcode to work, you can use this:

此外,如果您希望read代码正常工作,可以使用以下命令:

while read -r line
do
    printf "%s\n" "$line"
done < file.txt
[[ -n $line ]] && printf '%s' "$line"

This is going to work because actually readwill place the last line into the variable, but it also will return false, thus breaking the while loop.

这将起作用,因为实际上read会将最后一行放入变量中,但它也会返回false,从而破坏 while 循环。

回答by Barmar

Your input file doesn't end in a newline.

您的输入文件不会以换行符结尾。

cat filesimply copies the file contents to standard output. It operates by characters, not lines, so it doesn't care if the file ends in a newline or not. But if it doesn't end in a newline, it won't add one to the output.

cat file只需将文件内容复制到标准输出即可。它按字符而不是行进行操作,因此它不关心文件是否以换行符结尾。但如果它不以换行符结尾,则不会在输出中添加一个。

read -r linewill read a line into the variable. It will only report success if the line ends in a newline. If the last line of the input doesn't end in newline, it reports an error, as if EOF had been reached. So the loop terminates when it tries to read the last line, instead of returning that line. That's why the script never displays the line beginning with the quick brown fox.

read -r line将一行读入变量。如果该行以换行符结尾,它只会报告成功。如果输入的最后一行没有以换行符结尾,它会报告一个错误,就好像已经到达 EOF 一样。因此,当它尝试读取最后一行时,循环终止,而不是返回该行。这就是脚本从不显示以the quick brown fox.

In general, Unix text-file programs are only defined to work on text files that end in newline. Their treatment of the last line if it doesn't have a newline is not usually specified.

通常,Unix 文本文件程序仅定义为处理以换行符结尾的文本文件。如果最后一行没有换行符,通常不会指定他们对最后一行的处理。

回答by Emil Sit

Your file.txtdoes not contain a newline at the end of the last line. Hence catdoes not show it.

file.txt在最后一行的末尾不包含换行符。因此cat不显示它。

Note that read.shdoes not display the last line at all... in read.sh, readis waiting for a complete line of input, and since the last line is not terminated by a newline, so it is not actually read.

请注意,read.sh根本不显示最后一行... in read.shread正在等待输入的完整行,并且由于最后一行未以换行符终止,因此实际上并未读取。