在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将基于以下任一方面:
- 将文件读入内存,然后写回(
ed
,ex
,其他编辑器)。 如果你的文件<1GB或者你有足够的内存,这应该没问题。 - 编写第二个副本,并有select地replace原来的(
sed -i
,awk
/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读取的情况下才可行。