我有一个包含两列名称和ID的文件。使用BASH,我想读取文件的所有行,并将每列分配给变量$ name和$ ID。列由空格分隔,我想确保包含文件中的最后一行。有人可以帮忙吗?
答案 0 :(得分:1)
你的问题可能是while read
循环中没有处理最后一行,如果它不以换行符结尾:
printf '%s %s\n%s %s' a b c d | while read x y ; do
printf '%s, %s\n' $x $y
done
您可以在一行中添加换行符,例如通过以下Perl oneliner:
perl -pe '$_ .= "\n" unless /\n/'
它为没有一行的行添加了换行符,它必须是最后一行。
检查:
printf '%s %s\n%s %s' a b c d \
| perl -pe '$_ .= "\n" unless /\n/' \
| while read x y ; do
printf '%s, %s\n' $x $y
done
如果您正在处理多个文件,请先处理它们,然后在每个文件的最后一行添加换行符:
perl -pe '$_ .= "\n" unless /\n/' -- files* | while read x y ; do ...
答案 1 :(得分:1)
要确保循环在解析无效行(例如文件末尾没有尾随换行符的行)之后运行,您可以使用备用测试来指示是否读取了任何数据:
while read -r name id _ || [[ $name ]]; do
printf 'Read name: %s, and id: %s\n' "$name" "$id"
done <input
在这里,如果$name
报告失败,我们检查read
是否为非空,如果确实发生了,则继续运行循环体。 _
变量&#34;吸收&#34;第3列及以后,只读取前两个。
因为这种方法并不依赖于管道,所以可以确保循环中设置的变量在其出口处持续存在:
name_count=0
while read -r name id _ || [[ $name ]]; do
name_count=$((name_count+1))
printf 'Read name: %s, and id: %s\n' "$name" "$id"
done <input
echo "Read a total of $name_count names"
否则可能会与BashFAQ #24发生冲突(&#34;我将变量设置在管道中的循环中。为什么它们在循环终止后消失?或者,为什么可以&#39;我管道数据读取?&#34;)。