unix 我如何限制(或截断)文本文件的行数?

nc1teljy  于 2023-01-25  发布在  Unix
关注(0)|答案(2)|浏览(176)

我想使用一个终端/shell来截断或限制文本文件的行数。
我有一个完整的文本文件目录,其中只有前50 k行是有用的。
如何删除所有超过50000的行?

ioekq8ef

ioekq8ef1#

使用sed确实非常简单:

sed -n '1,50000 p' filename

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

sqxo8psd

sqxo8psd2#

就地截断

要使用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

长参数名版本如下所示,包括有和没有backup参数:

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

新建文件

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

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,它是dequemaxlen=0上的绑定extend方法,这是Python中耗尽迭代器的最快方法(据我所知)。
我们不能简单地循环file对象,因为tell方法会被阻塞,所以我们需要iter(f.readline, '')技巧。
这个函数演示了上下文管理器,但是有点多余,因为Python会在退出函数时关闭文件。

>>> truncate('filename', 50000)

相关问题