Bash:猫和回声之间的区别

时间:2013-09-08 03:56:05

标签: bash

这是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

这是我在终端尝试的内容:

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

我的问题是:为什么read.sh不显示cat file.txt之类的最后一行?

4 个答案:

答案 0 :(得分:7)

因为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

文件末尾没有\n

另一方面,

echo将在您收到消息时添加新行(如果没有消息)。

答案 1 :(得分:4)

其他答案是正确的,file.txt的末尾根本没有换行符。

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

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

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

此外,如果您希望read代码有效,可以使用此代码:

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

这样做是因为实际上read会将最后一行放入变量中,但它也会返回 false ,从而打破了while循环。

答案 2 :(得分:1)

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

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

read -r line会在变量中读取一行。如果该行以换行符结尾,它将仅报告成功。如果输入的最后一行未以换行结束,则会报告错误,就好像已达到EOF一样。因此,循环在尝试读取最后一行时终止,而不是返回该行。这就是为什么脚本永远不会显示以the quick brown fox开头的行。

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

答案 3 :(得分:0)

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

请注意,read.sh根本不显示最后一行...在read.sh中,read正在等待完整的输入行,并且因为最后一行未终止通过换行符,所以实际上并没有阅读。