还有一些其他答案没有涵盖的问题:
从分隔文件读取
# ':' is the delimiter here, and there are three fields on each line in the file
# IFS set below is restricted to the context of `read`, it doesn't affect any other code
while IFS=: read -r field1 field2 field3; do
# process the fields
# if the line has less than three fields, the missing fields will be set to an empty string
# if the line has more than three fields, `field3` will get all the values, including the third field plus the delimiter(s)
done < input.txt
使用进程替换从另一个命令的输出读取
while read -r line; do
# process the line
done < <(command ...)
这种方法优于命令…|同时读取-r行;做因为while循环在当前shell中运行,而不是像后者那样在子shell中运行。请参阅相关文章。在while循环内修改的变量不会被记住。
正在从空分隔输入读取,例如find-打印0
while read -r -d '' line; do
# logic
# use a second 'read ... <<< "$line"' if we need to tokenize the line
done < <(find /path/to/dir -print0)
相关阅读:BashFAQ/020-如何查找和安全处理包含换行符、空格或两者的文件名?
一次读取多个文件
while read -u 3 -r line1 && read -u 4 -r line2; do
# process the lines
# note that the loop will end when we reach EOF on either of the files, because of the `&&`
done 3< input1.txt 4< input2.txt
根据@chepner的回答:
-u是bash扩展。对于POSIX兼容性,每个调用看起来都像read-rX<&3。
将整个文件读入数组(Bash版本早于4)
while read -r line; do
my_array+=("$line")
done < my_file
如果文件以不完整的行结尾(末尾缺少换行符),则:
while read -r line || [[ $line ]]; do
my_array+=("$line")
done < my_file
将整个文件读取到阵列中(Bash版本4x及更高版本)
readarray -t my_array < my_file
or
mapfile -t my_array < my_file
然后
for line in "${my_array[@]}"; do
# process the lines
done
有关shell内置read和readarray命令的更多信息-GNU关于IFS的更多信息-维基百科BashFAQ/001-如何逐行(和/或逐字段)读取文件(数据流、变量)?
相关帖子:
在Bash中从文本文件创建数组两种读取只有一行的文件的方法有什么区别?与猫相比,在读取循环时猛击速度非常慢,为什么?