gpt4 book ai didi

bash - 多行 perl 正则表达式在没有 slurp 的情况下替换大文件

转载 作者:行者123 更新时间:2023-11-29 09:34:33 26 4
gpt4 key购买 nike

我有一个文件,它比需要运行此脚本的服务器上的可用内存量大得多。

在那个文件中,我需要运行一个基本的正则表达式,它一次跨两行查找和替换。我已经研究过使用 sed、awk 和 perl,但在这种情况下我无法让它们中的任何一个正常工作。

在一个较小的文件上,以下行完成了我需要的工作:perl -0777 -i -pe 's/,\s+\)/\n\)/g' inputfile.txt

本质上,只要一行以逗号结尾而下一行以右括号开始,请删除逗号。

当我尝试在我的生产文件上运行它时,几分钟后我在终端中收到消息“Killed”并且文件内容被完全删除。在那期间我一直在观察内存使用情况,正如预期的那样,它以 100% 的速度运行并大量使用交换空间。

有没有办法让该 perl 命令一次在两行上运行,或者有可能实现相同结果的替代 bash 命令?

如果通过保持文件大小相同更容易,那么我还可以选择用空格字符替换逗号。

最佳答案

一个相当直接的逻辑:

  • 打印一行,除非它以逗号结尾(需要检查下一行,也许将其删除)

  • 如果前一行 ($p) 有逗号,则打印它;如果当前行以 ) 开头,则不打印它

perl -ne'
if ($p =~ /,$/) { $p =~ s/,$// if /^\s*\)/; print $p };
print unless /,$/;
$p = $_
' file

可以通过丢失一个正则表达式(因此引擎启动开销减少)和一些数据副本来提高效率,但代价是代码更加笨拙,需要额外的逻辑和检查。

使用文件测试

hellohere's a comma,which was fine(but here's another,) which has to go,and that was another good one.end

The above fails to print the last line if it ends in a comma. One fix for that is to check our buffer (previous line $p) in an END block, so to add at the end

END { print $p if $p =~ /,$/}

这是检查 -n/-p 单行中尾随缓冲区或条件的一种相当常用的方法。

另一个修复方法,效率较低但代码可能更清晰,是替换语句

print unless /,$/;

print if (not /,$/ or eof);

这确实会在文件的每一行上运行 eof 检查,而 END 运行一次

关于bash - 多行 perl 正则表达式在没有 slurp 的情况下替换大文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58108791/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com