43

我想使用终端/外壳来截断或以其他方式将文本文件限制为一定数量的行。

我有一个完整的文本文件目录,每个文件只有前约 50k 行有用。

如何删除超过 50000 的所有行?

4

2 回答 2

90

就地截断

要使用 sed 就地截断文件,您可以执行以下操作:

sed -i '50001,$ d' filename
  • -i意味着到位。
  • d意思是删除。
  • 50001,$表示从 50001 到结尾的行。

您可以通过添加扩展参数来备份文件-i,例如,.backup.bak

sed -i.backup '50001,$ d' filename

OS-X 或 FreeBSD中,您必须为-i- 提供一个参数,以便在避免备份的同时执行此操作:

sed -i '' '50001,$ d' filename

长参数名称版本如下,有和没有备份参数:

sed --in-place '50001,$ d' filename
sed --in-place=.backup '50001,$ d' filename

新文件

要创建一个新的截断文件,只需从头重定向到新文件:

head -n50000 oldfilename > newfilename
  • -n50000表示行数,head 否则默认为 10。
  • >意味着重定向到,覆盖任何其他可能存在的东西。
  • 如果您要附加到新文件中,请替换>>>

不幸的是,您无法重定向到同一个文件,这就是为什么建议使用 sed 进行就地截断的原因。

没有sed?试试 Python!

这比 sed 打字要多一些。毕竟 Sed 是“流编辑器”的缩写,这是使用它的另一个原因,它是该工具适合的用途。

这是在 Linux 和 Windows 上使用 Python 3 测试的:

from collections import deque
from itertools import islice

def truncate(filename, lines):
    with open(filename, 'r+') as f:
        blackhole = deque((),0).extend
        file_iterator = iter(f.readline, '')
        blackhole(islice(file_iterator, lines))
        f.truncate(f.tell())

解释Python:

黑洞就像/dev/null. 这是with上的绑定extend方法,这是在 Python 中耗尽迭代器的最快方法(我知道)。dequemaxlen=0

我们不能简单地循环文件对象,因为tell方法会被阻塞,所以我们需要这个iter(f.readline, '')技巧。

这个函数演示了上下文管理器,但它有点多余,因为 Python 会在退出函数时关闭文件。用法很简单:

>>> truncate('filename', 50000)
于 2014-12-27T22:25:59.693 回答
10

确实很容易使用 sed:

sed -n '1,50000 p' filename

这只会打印文件“文件名”中的第 1 到 50000 行。

于 2013-09-26T04:18:28.757 回答