编写Bash脚本时,有时会遇到需要逐行读取文件的情况。例如,您可能有一个文本文件,其中包含应由脚本处理的数据。

在本教程中,我们将讨论如何在Bash中逐行读取文件。

逐行读取文件语法

逐行读取文件的最通用语法如下:

while IFS= read -r line
do
  echo "$line"
done < input_file

等效的单行版本:

while IFS= read -r line; do echo $line; done < input_file

它是如何工作的?

输入文件(input_file)是您要打开的文件的名称,以通过read命令读取。read命令逐行读取文件,并将每一行分配给line变量。处理完所有行后,while循环将终止。内部字段分隔符(IFS)设置为空字符串,以保留前导和尾随空格,这是read命令的默认行为。

逐行读取文件示例

让我们看下面的例子。假设我们有一个名为的文件,distros.txt其中包含一些最流行的Linux发行版及其软件包管理器的列表,并用逗号(,)分隔:

distros.txt

Ubuntu,apt
Debian,apt
CentOS,yum
Arch Linux,pacman
Fedora,dnf

要逐行读取文件,可以在终端中运行以下代码:

while IFS= read -r line
do
  echo "$line"
done < distros.txt

代码将逐行读取文件,将每一行分配给一个变量,然后回显该变量。基本而言,您将看到与使用cat命令显示文件内容相同的输出。

如果只想打印使用apt的发行版怎么办?一种方法是使用if语句,并检查该行是否包含apt 子字符串

while IFS= read -r line
do
  if [[ "$line" == *"apt"* ]]; then
    echo "$line"
  fi
done < distros.txt
Ubuntu,apt
Debian,apt

逐行读取文件时,您还可以将多个变量传递给read命令,该命令将根据将该行拆分为多个字段IFS。第一个字段分配给第一个变量,第二个字段分配给第二个变量,依此类推。如果字段多于变量,则剩余字段将分配给最后一个变量。

在下面的例子中,我们IFS设置为逗号(,)和通过两个变量distropm读取命令。从行的开始到第一个逗号的所有内容都将分配给第一个变量(distro),而行的其余部分将分配给第二个变量(pm):

while IFS=, read -r distro pm
do
  echo "$pm" is the package manager for "$distro"
done < distros.txt
apt is the package manager for Ubuntu
apt is the package manager for Debian
yum is the package manager for CentOS
pacman is the package manager for Arch Linux
dnf is the package manager for Fedora

替代文件读取方法

使用流程替代

进程替换使您可以将命令的输出作为文件名传递:

while IFS= read -r line
do
  echo "$line"
done < <(cat input_file )

使用here字符串

Here String是Here文档的变体。该字符串(cat input_file )将保留换行符:

while IFS= read -r line
do
  echo "$line"
done <<< $(cat input_file )

使用文件描述符

您还可以使用文件描述符将输入提供给循环:

while IFS= read -r -u9 line
do
  echo "$line"
done 9< input_file

使用文件描述符时,请使用4到9之间的数字,以避免与Shell内部文件描述符冲突。

结论

在Bash中,我们可以通过提供文件名作为while读取循环的输入来逐行读取文件。

如果您有任何问题或反馈,请随时发表评论。

如果你喜欢我们的内容可以选择在下方二维码中捐赠我们,或者点击广告予以支持,感谢你的支持