如何使用 awk 打印文件的倒数第二行

如何使用 awk 打印文件的倒数第二行

我有多个文件,每个文件的编号或记录不同。我想要一个 awk 命令来打印它们的倒数第二行并执行一些更改。我想要这样的东西:(这个当然行不通)

awk '( NR == FNR-1 ), $0","' *.txt

答案1

awk当记录到来时读取它们,如果尚未读取这些记录,则不知道这些记录距离末尾有多远(在读取和处理当前记录后很可能添加额外的记录)。

与 相反sed,它甚至无法分辨哪一条是最后一条记录(sed具有$它通过提前内部读取一条记录实际实现的地址,因此它知道哪一条是最后一条)。

但是,您可以在处理每个输入文件(在语句中)后在特殊语句的末尾END或使用 GNU进行一些处理。awkENDFILE

因此,您可以在处理时保存最后两条记录,然后在END/ENDFILE语句中调出保存位置的倒数第二条记录。

例如:

awk '{prevlast = last; last = $0}
     END {if (NR >= 2) print "penultimate:", prevlast}' < input

或者:

gawk '{prevlast = last; last = $0}
      ENDFILE {
       if (FNR >= 2) print "penultimate for", FILENAME ":", prevlast
      }' file1 file2

或者将其概括为从末尾开始的第n 个:

awk -v n=2 '{saved[NR % n] = $0}
     END {if (NR >= n) print saved[(NR + 1) % n]}' < input

gawk -v n=2 '{saved[FNR % n] = $0}
     ENDFILE {if (FNR >= n) print saved[(FNR + 1) % n]}' file1 file2

答案2

,在倒数第二行末尾添加逗号并就地修改每个文件。

sed解决方案:

样本file1.txt

C2-C1 1.5183
C3-C2 1.49
C3-C1 1.4991
O4-C3 1.4104
C1-C2-C3 59.78

样本file2.txt

C2-C1 1.5052
C3-C2 1.505
C3-C1 1.5037
S4-C3 1.7976
C1-C2-C3 59.95

sed -i 'x; ${s/.*/&,/;p;x}; 1d' file*.txt

查看结果:

$ head file[12].txt
==> file1.txt <==
C2-C1 1.5183
C3-C2 1.49
C3-C1 1.4991
O4-C3 1.4104,
C1-C2-C3 59.78

==> file2.txt <==
C2-C1 1.5052
C3-C2 1.505
C3-C1 1.5037
S4-C3 1.7976,
C1-C2-C3 59.95

相关内容