我有多个文件,每个文件的编号或记录不同。我想要一个 awk 命令来打印它们的倒数第二行并执行一些更改。我想要这样的东西:(这个当然行不通)
awk '( NR == FNR-1 ), $0","' *.txt
答案1
awk
当记录到来时读取它们,如果尚未读取这些记录,则不知道这些记录距离末尾有多远(在读取和处理当前记录后很可能添加额外的记录)。
与 相反sed
,它甚至无法分辨哪一条是最后一条记录(sed
具有$
它通过提前内部读取一条记录实际实现的地址,因此它知道哪一条是最后一条)。
但是,您可以在处理每个输入文件(在语句中)后在特殊语句的末尾END
或使用 GNU进行一些处理。awk
ENDFILE
因此,您可以在处理时保存最后两条记录,然后在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