9

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

4 回答 4

10

因为 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另一方面,如果没有消息,则在回显消息时始终会添加新行。

于 2013-09-08T04:03:27.847 回答
7

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

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

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

-nflag 告诉 echo 不要输出尾随的换行符。

此外,如果您希望您的read代码工作,您可以使用这个:

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

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

于 2013-09-08T04:10:50.397 回答
4

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

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

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

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

于 2013-09-08T04:05:04.900 回答
1

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

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

于 2013-09-08T04:05:45.590 回答