Contents

在Bash中循环浏览文件的内容

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