循环遍历文件时,如何知道自己位于最后一行?

循环遍历文件时,如何知道自己位于最后一行?

我有一个名为的文件,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

相关内容