在Bash中循环浏览文件的内容
Contents
1. 概述
在本教程中,我们将看到如何逐行遍历文件的内容。这听起来像是一项微不足道的任务,但我们需要注意一些警告。 本文中的示例已经在 Bash 中进行了测试。但它们也应该适用于其他 POSIX 兼容的 shell。
2. 示例文件
假设我们有一个文本文件,并且我们想要回显每一行(当然不使用cat )。该文件名为lorem-ipsum.txt,其内容为:
Lorem
ipsum
dolor
sit
amet
3. while循环
为了输出每一行,我们创建一个 bash 脚本并使用一个while 循环来遍历我们的文件并将其命名为echo-lines.sh:
while read line; do
echo $line
done < lorem-ipsum.txt
使用尖括号,我们将lorem-ipsum.txt的内容逐行传递给 while 循环。当我们运行它时,输出与我们预期的一样:
$ ./echo-lines.sh
Lorem
ipsum
dolor
sit
amet
似乎我们找到了一种简单的方法来遍历文件的内容。但是,在以下部分中,我们将看到一些需要注意的警告。
3.1.白色空间
现在,假设我们的文件在第 2 行包含一些前导空格:
Lorem
ipsum
dolor
sit
amet
同样,让我们运行我们的脚本:
$ ./echo-lines.sh
Lorem
ipsum
dolor
sit
amet
我们得到与以前相同的输出。在读取文件的行时,bash 会忽略前导空格,因为它认为它们是分隔符。 为了解决这个问题,我们需要清除输入字段分隔符或IFS 环境变量。我们在脚本的开头添加一条语句:
IFS=''
while read line; do
echo $line
done < lorem-ipsum.txt
在第一行,我们清除输入字段分隔符,现在我们的脚本将打印预期结果:
$ ./echo-lines.sh
Lorem
ipsum
dolor
sit
amet
3.2. 转义字符
我们还没有完全做到。让我们看看当我们的文件包含反斜杠(bash 中使用的转义字符)时会发生什么:
Lorem
ipsum
dolor
sit\
amet
同样,我们运行我们的脚本:
$ ./echo-lines.sh
Lorem
ipsum
dolor
sitamet
正如我们从结果中看到的,不仅反斜杠被删除,而且最后两行也被打印为一行。默认情况下,read 命令会将反斜杠视为转义字符。这会导致意想不到的结果,比如在我们的例子中,下一个换行符被忽略了。
为了解决这个问题,我们将使用read -r禁用反斜杠解释:
IFS=''
while read -r line; do
echo $line
done < lorem-ipsum.txt
现在它正确地打印了我们文件的内容:
$ ./echo-lines.sh
Lorem
ipsum
dolor
sit\
amet