【问题标题】:Awk replacement for a multiline perl substitution operation用于多行 perl 替换操作的 awk 替换
【发布时间】:2018-03-13 04:47:35
【问题描述】:

我使用这个 Perl 命令来删除数据库转储的块。它从包含字符串TABLE DATA; Schema: pgq; 的注释行开始,稍后以字符序列\. 本身在一行结束。删除所有匹配项。

perl -p0e 's/\n--[^\n]*TABLE DATA; Schema: pgq;.*?\n\\\.\n//gs'

这有效,除非处理由于perl bug that's been fixed in 5.22 而导致的大于几千兆字节的数据库转储。我被困在 Perl 5.18 (Ubuntu 14.04) 上,升级不是一个选项。

我正在考虑使用 awk 和 -vRS-vORS 变量以及可能的 gsub 运算符重写 Perl 表达式,但我似乎找不到任何适用于我的用例的示例。使用 awk 是否有可能?

我正在使用GNU Awk 4.0.1

【问题讨论】:

  • 为什么不在你的 HOME 目录中安装一个新的 perl 呢?
  • 不幸的是,这是在没有 Internet 访问权限的服务器上,所以我必须使用我所拥有的。正如我所提到的,升级 Perl 不是一种选择。我正在寻找解决方法。
  • 如果您edit 您的问题包含简洁、可测试的样本输入和预期输出,您将更有机会获得正确答案。包括难以处理的案件,而不仅仅是晴天的案件。是的,它只是软件,所以一切皆有可能。
  • .*?\n\\\.\n 应该是 (?:(?!\n\\\.\n).)*+\n\\\.\n。您可以通过将其替换为 (?:(?:(?!\n\\\.\n).){65535})*+(?:(?!\n\\\.\n).)*+\n\\\.\n 来绕过限制

标签: bash perl awk


【解决方案1】:

按行工作不会得到同样的效果吗?这将绕过“长字符串”正则表达式错误:

perl -ne 'print unless /^--.*TABLE DATA; Schema: pgq;/ .. ($_ eq "\\.\n")'

我们一次处理一行输入 (-n)。我们打印每一行,除非我们在一个要被剥离的块中。

.. operator(在标量上下文中)跟踪我们的状态(我们是否应该跳过)。可跳过区域的开头由条件/^--.*TABLE DATA; Schema: pgq;/ 标记(即与当前行匹配的正则表达式);可跳过区域的结尾由$_ eq "\\.\n" 标记(即,正好包含\. 的行)。

【讨论】:

  • 哇,这似乎有效。你能评论一下语法吗?在我的正则表达式中,我必须在找到第一个匹配项后使用非贪婪修饰符。您的解决方案似乎颠倒了这种方法。
  • @Jeff 已编辑。这有帮助吗?
  • 感谢 melpomene 指出这一点,但您使用 perl -0 读取整个文件。 (应该是perl -0777)当您的代码因大于 2GB 的文件而崩溃时,您的第一个想法应该是在其他人的代码中搜索错误,而应该是“我为什么要从一个一次性归档”?您不将所有数据一直保存在内存中是有原因的。
  • @Jeff:“哇,这似乎有效”。由于几个原因,它也可能比吞食千兆字节的数据要快得多。开发人员在实现缓冲 I/O 时并不是想把你搞砸。
猜你喜欢
  • 2017-06-16
  • 1970-01-01
  • 1970-01-01
  • 2011-01-23
  • 2014-03-27
  • 2015-08-24
  • 2016-10-29
  • 2012-03-29
相关资源
最近更新 更多