Bash逐行读文件

用 Bash 处理文件时,经常有一个需求是逐行读取文件的内容,并完成一定操作,那么应该如何读取文件呢?

通过搜索,我们不难得出如下的答案,但是这个是错误的!

while read line; do
    echo $line
done < filename.txt

怎么错了?

当我们的文件最后一行没有换行符时,最后一行并不会被打印出来。

例如,我的 filename.txt 长这样(第4行最后的 % 是提示我们文件没有以换行符结束的标志,不是文件内容):

$ cat filename.txt
1
2
3%

此时,运行上述 Bash 代码会得到:

$ while read line; do
    echo $line
done < filename.txt
1
2

为什么错了?

我们可以看到,上面的 read 的颜色和 echo 一样,说明这是个内置的函数,通过查询Bash文档的Builtin章节得知

The exit status is zero, unless end-of-file is encountered, …

退出的状态码是0,除非读到了 EOF 等内容

这里我们知道了,在读到第三行的时候,read 确实会把读到的内容赋值给 line,但是因为其退出状态不是 0,因此 while 循环的条件不被满足,因此无法执行循环中的内容(echo $line)。

如何改正?

既然是因为 while 循环使用了 read 的退出码,那只要改个条件即可(这个条件既可以实现最后一行为true,同时又避免了死循环):

while read line || [ -n "$line" ] ; do
    echo $line
done < filename.txt

You may also like...

发表评论

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据

%d 博主赞过: