在unix命令行中移除文件的前N行

我试图从一个非常非常大的文件中删除前37行。 我开始尝试sed和awk,但他们似乎需要将数据复制到一个新的文件。 我正在寻找一个“删除线路就位”的方法,不像sed -i不做任何types的副本,而只是删除现有文件中的行。

这是我所做的…

 awk 'NR > 37' file.xml > 'f2.xml' sed -i '1,37d' file.xml 

这两个似乎做了一个完整的副本。 有没有其他简单的CLI,可以做到这一点,没有一个完整的文件遍历?

使用UNIX实用程序进行就地编辑没有简单的方法,但是这里有一个就地文件修改解决scheme,您可能可以修改以便为您工作(Robert Bonomi在https://groups.google.com/forum/#!; topic / comp.unix.shell / 5PRRZIP0v64 ):

 count=$(head -37 "$file" |wc -c) dd if="$file" bs="$count" skip=1 of="$file" 

最后的文件应该是比原来小$count字节的字节(因为目标是从头开始删除$count个字节),所以要完成我们必须删除最后的$count字节。 在Linux这样的GNU系统上,可以通过以下方式来完成:

 truncate -s "-$count" "$file" 

看到我参考的谷歌组线程的其他build议和信息。

Unix文件语义不允许截断文件的前面部分。

所有解决scheme将基于以下任一方面:

  1. 将文件读入内存,然后写回( edex ,其他编辑器)。 如果你的文件<1GB或者你有足够的内存,这应该没问题。
  2. 编写第二个副本,并有select地replace原来的( sed -iawk / tail > foo )。 只要您有足够的可用磁盘空间作为副本,这没什么问题,不要在意等待。

如果文件太大而无法为您工作,则可以根据读取文件的内容来解决该问题。

也许你的读者跳过评论或空白行? 如果是这样,那么你可以编写一个读者忽略的消息,确保它具有与文件中第37行相同的字节数,并用dd if=yourdata of=file conv=notrunc覆盖dd if=yourdata of=file conv=notrunc覆盖文件的开头。

ed是标准的编辑器:

 ed -s file <<< $'1,37d\nwq' 

这个副本必须在某个时候创build​​ – 为什么在阅读“修改”文件的时候呢? stream更改副本,而不是存储它?

我在想什么 – 创build一个命名pipe道“file2”,这是相同awk'NR> 37'file.xml的输出或任何; 那么谁读取file2将不会看到前37行。

缺点是每次处理文件时都会运行awk,所以只有在很less读取的情况下才可行。