如何删除文件中的某些行(使用行号)?

如何删除文件中的某些行(使用行号)?

我想从文件中删除某些特定行。假设它是第 20-37 行,然后是第 45 行。如果不指定这些行的内容,我该怎么做?

答案1

sed,像这样:

sed '20,37d; 45d' < input.txt > output.txt

如果您想就地执行此操作:

sed --in-place '20,37d; 45d' file.txt

答案2

如果该文件适合内存,您也可以使用ed.
这些命令与上面的命令非常相似,sed其中一个显着差异:您必须按降序传递要删除的行号/范围列表(从最高的行号/范围到最低的行号/范围)。原因是,当您使用 删除/插入/拆分/连接行时ed,文本缓冲区会在每个子命令之后更新,因此如果您删除某些行,则以下行的其余部分将不再位于缓冲区中的同一位置。执行下一个子命令。所以你必须从头开始1
到位编辑:

ed -s in_file <<IN
45d
20,37d
w
q
IN

或者

ed -s in_file <<< $'45d\n20,37d\nw\nq\n'

或者

printf '%s\n' 45d 20,37d w q | ed -s in_file

如果您想打印结果输出而不是写入文件,请将write替换为 rint。,p如果您想保持原始文件完整并写入另一个文件,您可以将新文件名传递给write 子命令:

ed -s in_file <<IN
78,86d
65d
51d
20,37d
w out_file
q
IN

1 除非您愿意在每次delete 之后计算新的行号,这对于这种特殊情况来说非常简单(删除第 20-37 行,即 18 行后,第 45 行变为第 27 行),因此您可以运行:

ed -s in_file <<IN
20,37d
27d
w
q
IN

但是,如果您必须删除多个行号/范围,则向后操作是理所当然的。

答案3

只需将其读入内存,更改它,然后写回即可。你可以做类似的事情

filename = "foo"
f = open(filename, 'r+')                                                                                                                                 
linenums = [1, 3]                                                                                                                                            
s = [y for x, y in enumerate(f) if x not in [line-1 for line in linenums]]                                                                                                                                          
f.seek(0)
f.write(''.join(s))
f.truncate(f.tell())
f.close()

使用 5 行文件进行测试。致谢http://pleac.sourceforge.net/pleac_python/fileaccess.html,请参阅“在没有临时文件的情况下就地修改文件”部分。也可以看看https://stackoverflow.com/questions/125703/how-do-i-modify-a-text-file-in-python

一些注意事项:

  1. 可以先截断文件,然后写入文件,而不是如上所述先写入,然后截断。但是,我不知道有哪个 Python 标志允许读取,然后进行截断写入。但也许我遗漏了一些东西,因为该文件并不那么清楚。这让我想到

  2. 有时 Python 文档真的很糟糕。看 http://docs.python.org/library/functions.html#open

    模式“r+”、“w+”和“a+”打开文件进行更新(请注意,“w+”会截断文件)。

    这对你来说意味着什么吗? “开放更新”到底是什么?

  3. 我不知道在 python 中执行此操作是否比在 unixy 中(例如流编辑器)更好。它可能更便携,但我不知道 sed 的便携性如何。我只是这样写,因为我对低级编程比使用经典的 unix 工具更舒服,如果它们完全按照你的要求做,那就很好,但(我认为)通常不太灵活。

  4. 这种方法(操作内存中的文件)用内存换取磁盘空间。它应该可以在具有几 Gb 内存的机器上运行,对于高达几百 Mb 的文件。 Python 不能非常有效地处理字符串,因此切换到 C/C++ 会稍微提高性能并大大减少内存使用量。

答案4

您可以在 Ex 模式下使用 Vim:

ex -sc '20,37d|45d|x' file
  1. d删除

  2. x保存并关闭

相关内容