如何使用 sed 搜索值列表的任何成员

How to search for any member of a list of values with sed

不确定如何恰当地提出问题,但这是用例:

我可以编写一个 for 循环并通过一堆 sed 语句循环,如下所示:

sed -i.bu '/<way id="1_bad_way_entry".*/,/<\/way>/d' in.xml

但是...这需要大约 250 个周期来完成一个 18G 的文件和相关的磁盘写入等,现在每个周期大约需要 18 分钟(旋转磁盘...将通过切换机器很快解决这个问题。更新: SSD 提高到每个周期约 6.5 分钟)。

有什么方法可以让 sed 匹配 bad_ways 中的 任何 条目并在 1 遍中执行此操作?

或者,是否有比 sed 更好的工具?提前致谢!

您可以使用命令替换 assemble 运行 上的 sed 脚本。

(注意:在下面我使用 sed-E 选项来保存一些反斜杠;如果你不这样做,你必须通过包含根据需要反斜杠。)

例如,假设 bad_ways 文件是这样的:

one
two
three

并且 huge_file 是这样的:

everything starts with a zero, then one is next, then two, then three, finally four

您可以使用以下命令完成任务,将 bad_ways 中列出的所有模式替换为 XXX:

sed -E 's/'"$(sed -zE 's/\n([^$])/|/g' bad_ways)"'/XXX/g' huge_file

则输出为

everything starts with a zero, then XXX is next, then XXX, then XXX, finally four

如您所见,作用于 huge_filesed 脚本是由三个字符串连接而成的:

  1. s/ 这是单引号(你应该总是喜欢单引号,除非你需要双引号,如 2.)
  2. sed -zE 's/\n([^$])/|/g' bad_ways 的输出,双引号允许命令替换,并生成 one|two|three
  3. /XXX/g.

所有这些导致字符串 s/one|two|three/XXX/g

这显然不是您的脚本所需的字符串,但我希望这个答案向您展示了一个示例 如何使用命令替换 $(…) 以及使用 [=30 进行适当引用=] 和 " 动态制作命令(sedawk 或其他).

事后看来,此答案基于与评论链接中的答案相同的 "philosophy"。但是我不是临时将脚本保存到文件中。如果脚本本身很小(根据您的描述,它很小),这可能不太重要。