如何在Bash中逐行读取文件
编写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设置为逗号(','),并将两个变量'distro'和'pm'传递给read命令。
从行的开始到第一个逗号的所有内容都将分配给第一个变量('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内部文件描述符冲突。