我有一个非常大的文件,需要从中删除模式。问题是,文件中没有换行符。要删除的模式如下所示:... 1666 more items
其中 1666 可以是任何数字。
答案1
我不知道sed
这是否是最好的工具。我个人去perl
寻找这样的事情,并提出了这个:
perl -pe 'BEGIN{ $/ = " more items"; } s/\.\.\.\s\d+ more items$//;'
-e
是要执行的程序文本。
-p
意味着对每个记录对程序文本执行一次隐式循环(默认情况下一条记录是一行,请参阅下面的修改)。
首先将记录分隔符$/
从默认的换行符 ( \n
) 设置为字符串“more items”;由 指示的块BEGIN { }
在开始时完成一次。
现在,它将一次读取一个块的输入,直到(并包括)记录分隔符。因此,每个循环的输入缓冲区中都会有“无论如何……还有 1234 个项目”。
这s/\.\.\.\s\d+ more items$//
是一种替换,它删除任何由三个点组成的字符串(转义以删除“任何字符”的特殊含义),后跟空格 (\s),后跟一个或多个数字 ( \d+
) 以及文本“more items”记录结束 ( $
)。匹配记录的结尾不是必需的,但可能会加快匹配速度。
由于该选项,默认情况下会打印结果-p
。
答案2
如果您使用 GNU sed(有时称为gsed
),那么长行就可以达到内存限制。
如果您使用其他 sed,例如在 MacOS 或 BSD 上,则会有限制。这GNU sed 手册解释:
对于那些想要编写可移植 sed 脚本的人,请注意,已知某些实现会将行长度(模式和保留空间)限制为不超过 4000 字节。 POSIX 标准指定符合要求的 sed 实现应支持至少 8192 字节的行长度。 GNU sed 对行长度没有内置限制;只要它可以 malloc() 更多(虚拟)内存,您就可以根据需要提供或构造行。
因此,如果您有 GNU sed,您可以使用 sed 解决方案,例如建议的@菲利普斯:
sed 's/\.\.\. [0-9]* more items//g'
使用 awk
作为替代方案,如果您有 GNU awk(有时称为gawk
),请尝试:
awk -v RS='\.\.\. [0-9]* more items' 1 ORS="" File
因此使用正则表达式\.\.\. [0-9]* more items
作为记录分隔符在输入和空字符串作为记录分隔符关于输出。这具有删除正则表达式的任何匹配的效果\.\.\. [0-9]* more items
。
因为 awk 一次只读入一条记录,所以这比 sed 解决方案消耗的内存更少。