如何使用sed删除文件的最后n行

我想从文件末尾删除一些n行。 这可以使用sed完成吗?

例如,要删除2到4行,我可以使用

$ sed '2,4d' file 

但是我不知道行号。 我可以删除最后一行使用

 $sed $d file 

但我想知道从最后删除n行的方法。 请让我知道如何使用sed或其他方法做到这一点。

我不知道sed ,但是可以用head来完成:

 head -n -2 myfile.txt 

从sed单线 :

 # delete the last 10 lines of a file sed -e :a -e '$d;N;2,10ba' -e 'P;D' # method 1 sed -n -e :a -e '1,10!{P;N;D;};N;ba' # method 2 

似乎是你在为什么looing。

一个有趣的和简单的sedtac解决scheme:

 n=4 tac file.txt | sed "1,$n{d}" | tac 

注意

  • 双引号"是shell需要在sed命令中插入$nvariables,在单引号中不会执行插值操作。
  • tac是一只cat逆转,见man 1 tac
  • sed中的{}用于分隔$nd (如果不是,shell尝试插入不存在的$ndvariables)

如果硬编码是一个选项,你可以使用顺序调用sed。 例如,要删除最后三行,最后一行删除三行:

 sed '$d' file | sed '$d' | sed '$d' 

你可以用头来这个。

使用

$ head --lines=-N file > new_file

其中N是要从文件中删除的行数。

原始文件的内容减去最后N行现在在new_file中

使用sed ,但让shell执行math运算,目标是通过给出一个范围来使用d命令(删除最后23行):

 sed -i "$(($(wc -l < file)-22)),\$d" file 

从里面去掉最后3行:

 $(wc -l < file) 

给出文件的行数:说2196

我们要删除最后的23行,所以对于左侧或范围:

 $((2196-22)) 

给出: 2714因此,shell解释后的原始sed是:

 sed -i 2174,$d file 

-i进行就地编辑,文件现在是2173行!

这可能适用于你(GNU sed):

 sed ':a;$!N;1,4ba;P;$d;D' file 

为了完整性,我想添加我的解决scheme。 我结束了这个与标准ed

 ed -s sometextfile <<< $'-2,$d\nwq' 

这将使用就地编辑删除最后两行(尽pipe它在/tmp 使用临时文件!!)

要真正截断非常大的文件,我们需要truncate命令。 它不知道线条,但tail + wc可以将线路转换为字节:

 file=bigone.log lines=3 truncate -s -$(tail -$lines $file | wc -c) $file 

如果文件同时写入,则会有明显的竞争条件。 在这种情况下,使用head可能会更好 – 它从文件头(记忆磁盘IO)开始计算字节数,所以我们将总是在行边界上截断(如果文件被主动写入,可能会多于预期的行数):

 truncate -s $(head -n -$lines $file | wc -c) $file 

方便的一行,如果你失败login尝试把密码的地方的用户名:

 truncate -s $(head -n -5 /var/log/secure | wc -c) /var/log/secure 

在这里的答案,你会已经知道sed不是这个应用程序的最佳工具。

不过我认为有一种方法可以在使用sed时做到这一点; 这个想法是追加N行来保存空间,直到你能够读取而不会触及EOF。 当EOF被击中时,打印保持空间的内容并退出。

 sed -e '$!{N;N;N;N;N;N;H;}' -ex 

上面的sed命令将省略最后5行。

上面的大部分答案似乎都需要GNU命令/扩展:

  $ head -n -2 myfile.txt -2: Badly formed number 

对于更轻便的解决scheme:

  perl -ne 'push(@fifo,$_);print shift(@fifo) if @fifo > 10;' 

要么

  perl -ne 'push(@buf,$_);END{print @buf[0 ... $#buf-10]}' 

要么

  awk '{buf[NR-1]=$0;}END{ for ( i=0; i < (NR-10); i++){ print buf[i];} }' 

“10”是“n”。

尝试以下命令:

 n = line number tail -r file_name | sed '1,nd' | tail -r 

您可以使用wc -l <file>来获得行数的总数

head -n <total lines - lines to remove> <file>

它可以分3步完成:

a)计算要编辑的文件中的行数:

  n=`cat myfile |wc -l` 

b)从该数字中减去要删除的行数:

  x=$((n-3)) 

c)告诉sed从行号( $x )到结尾删除:

  sed "$x,\$d" myfile 

我更喜欢这个解决scheme

 head -$(gcalctool -s $(cat file | wc -l)-N) file 

其中N是要移除的行数。

 sed -n ':pre 1,4 {N;b pre } :cycle $!{P;N;D;b cycle }' YourFile 

posix版本

删除最后4行:

 $ nl -ba file | sort -k1,1nr | sed '1, 4 d' | sort -k1,1n | sed 's/^ *[0-9]*\t//' 

我想出了这个,其中n是你想要删除的行数:

 count=`wc -l file` lines=`expr "$count" - n` head -n "$lines" file > temp.txt mv temp.txt file rm -f temp.txt 

这有点迂回,但我认为这很容易遵循。

  1. 计算主文件中的行数
  2. 减去要从计数中删除的行数
  3. 打印出想要保存的行数并存储在临时文件中
  4. 将主文件replace为临时文件
  5. 删除临时文件

这将从file删除最后3行:

for i in $(seq 1 3); do sed -i '$d' file; done;