我有一个名为的文件,listing.txt
它包含如下数据:
1
2
3
4
5
然后,我使用以下命令循环遍历文件并对每一行执行操作:
IFS=$'\n'
while IFS= read -r inc; do
if [ $inc -eq 1 ]
then
echo "FIRST: $inc"
else
echo "MID: $inc"
fi
done </home/user/listing.txt
但我找不到检查它是否是最后一行的选项。如果我在最后一行,最好的查找方法是什么?
我见过许多讨论循环的页面,以及讨论从文件中获取最后一行的页面,但没有任何内容可以帮助我的循环知道它在最后一行。
答案1
获取文件的最后行号,也称为总行数。循环遍历文件,跟踪当前行号。如果当前行号等于最后一个行号,则执行某些操作。
#!/bin/bash
file="some-file.txt"
last_line=$(wc -l < $file)
current_line=0
while read -r line; do
current_line=$(($current_line + 1))
if [[ $current_line -ne $last_line ]]; then
# is NOT last line
else
# IS last line
fi
done < $file
答案2
位于最后一行意味着什么?这意味着在这一行之后没有任何行,因此一种策略是检查循环内当前行之后是否还有另一行。如果没有,你就在最后一行,否则你就在中间。
另一种技术是将行保留在循环外部的变量中,然后当循环结束时,变量包含最后一行。这样做的缺点是会使中间计算不正确,但您可能会找到解决方法。
答案3
重申 WAF 在评论中所说的内容,您可以使用它wc
来获取循环之前的行数并对其进行测试以捕获最后一行:
IFS=$'\n'
last=$(</home/user/listing.txt wc -l)
while IFS= read -r inc; do
if [ $inc -eq 1 ]
then
echo "FIRST: $inc"
elif [ $inc -eq $last ]
echo "LAST: $inc"
else
echo "MID: $inc"
fi
done </home/user/listing.txt
答案4
一种选择是“展开”循环的一部分,以便可以使用下一行的状态来确定当前行的处理:
{
IFS= read -r current
while IFS= read -r next; do
echo "MID: $current"
current=$next
done
echo "LAST: $current"
} </home/user/listing.txt
像这样的循环不需要了解有关行数或文件内容的任何信息。值得注意的是,它将与数据流一起工作,即从另一个进程通过管道输入的数据(请参见下面的示例)。
要执行与第一行不同的操作,只需将循环展开一点:
printf '%s\n' a b c d e | {
IFS= read -r first
echo "FIRST: $first"
IFS= read -r current
while IFS= read -r next; do
echo "MID: $current"
current=$next
done
echo "LAST: $current"
}
输出:
FIRST: a
MID: b
MID: c
MID: d
LAST: e