就地删除最后n行文件,而不会在gawk中多次打开它们

  • 本文关键字:gawk 最后 删除 文件 awk
  • 更新时间 :
  • 英文 :


https://www.baeldung.com/linux/remove-last-n-lines-of-file

awk -v n=3 'NR==FNR{total=NR;next} FNR==total-n+1{exit} 1' input.txt input.txt 
01 is my line number. Keep me please!
02 is my line number. Keep me please!
03 is my line number. Keep me please!
04 is my line number. Keep me please!
05 is my line number. Keep me please!
06 is my line number. Keep me please!
07 is my line number. Keep me please!

以下是删除最后n行的方法。但它不是就地完成的,文件会被读取两次,而且一次只处理一个文件。

如何就地删除多个文件的最后n行,而不使用一个gawk命令多次打开它们,但不使用任何其他外部命令?

使用您显示的示例,请尝试以下awk代码。不按照OP的要求使用任何外部公用设施。我们可以利用CCD_ 3程序的CCD_ 2块。

awk -v n="3" '
{
total=FNR
lines[FNR]=$0
}
END{
till=total-n
for(i=1;i<=till;i++){
print lines[i]
}
}
' Input_file

不需要阵列也不需要gawk的单程awk解决方案

--(除非你的文件在500 MB上,否则它可能会稍微慢一点):

rm -f file.txt
jot -c 30 51 > file.txt
gcat -n file.txt | rs -t -c$'n' -C'#' 0 5 | column -s'#' -t
1  3       7   9      13   ?      19   E      25   K
2  4       8   :      14   @      20   F      26   L
3  5       9   ;      15   A      21   G      27   M
4  6      10   <      16   B      22   H      28   N
5  7      11   =      17   C      23   I      29   O
6  8      12   >      18   D      24   J      30   P
mawk -v __='file.txt' -v N='13' 'BEGIN { 
OFS = FS = RS
RS = "^$"
getline <(__); close(__)

print $!(NF -= NF < (N+=_==$NF) ? NF : N) >(__) }'
度几乎不是问题:
115K rows 198 MB file took 0.254 secs
D_8

另一种方法,使用GAWK,带有选项BEGINFILE和ENDFILE特殊模式:

{ lines[++numLines] = $0 }
BEGINFILE { fname=FILENAME}
ENDFILE { prt() }
function prt(   lineNr,maxLines) {
close(fname)
printf "" > fname
maxLines = numLines - n
for ( lineNr=1; lineNr<=maxLines; lineNr++ ) {
print lines[lineNr] > fname
}
close(fname)
numLines = 0
}

我发现这是这个问题最简洁的解决方案。

$ gawk -i inplace -v n=3 -v ORS= -e '{ lines[FNR]=$0 RT }
ENDFILE {
for(i=1;i<=FNR-n;++i) {
print lines[i]
}
}' -- file{1..3}.txt

最新更新