使用 GNU sed 和 GNU find 时如何加速替换?

Posted

技术标签:

【中文标题】使用 GNU sed 和 GNU find 时如何加速替换?【英文标题】:How to accelerate substitution when using GNU sed with GNU find? 【发布时间】:2021-12-04 08:10:31 【问题描述】:

我有一个包含数百个目录的数值模拟结果;每个目录包含数百万个文本文件。

我需要用“wavelength_bc;”替换字符串“wavelength;”,所以我尝试了以下两种方法:

find . -type f -exec sed -i 's/wavelength;/wavelength_bc;/g'  \;

find . -type f -exec sed -i 's/wavelength;/wavelength_bc;/g'  +

很遗憾,上述命令需要很长时间才能完成(超过 1 小时)。

我想知道如何利用我机器上的核心数 (8) 来加速上面的命令?

我正在考虑将xargs-P 标志一起使用。我担心这会损坏文件;所以我不知道这是否安全?

总结:

find 一起使用时如何加速sed 替换? 使用xargs -P 并行运行是否安全?

谢谢

【问题讨论】:

是的 xargs -P 使用起来应该非常安全 @anubhava:谢谢!我现在正在尝试。你能写一个答案吗? 即使某些文件在xargs -P sed -i [...]的输入中被多次列出,它也应该是安全的(但效率较低),尽管当输入为来自find 的输出。 【参考方案1】:

xargs -P 应该可以安全使用,但是您需要使用find-print0 选项并通过管道连接到xargs -0 来处理带有空格或通配符的文件名:

find . -type f -print0 |
xargs -0 -I  -P 0 sed -i 's/wavelength;/wavelength_bc;/g' 

xargs 中的-P 0 选项将以并行模式运行。它将为您的 CPU 运行尽可能多的进程。

【讨论】:

-P 8 将始终并行运行 8 个作业,但 -P 0 将检查您的处理器并为该 CPU 运行尽可能多的并行作业。请注意,由于您有 8 核处理器,所以 -P 0 实际上与 -P 8 相同。 使用该命令,完成后:real 43m15.117s user 39m54.227s sys 53m27.121s 好的,这是一些改进【参考方案2】:

这可能对你有用(GNU sed 和并行):

find . -type f | parallel -q sed -i 's/wavelength;/wavelength_bc;/g' 

GNU 并行将运行与机器上并行的内核一样多的作业。

更复杂的用途可能涉及远程服务器和文件传输,请参阅here 和备忘单here。

【讨论】:

您必须转义分号才能使其正常工作! @s.ouchene 哎呀!替代方案是使用并行 -q 选项或将单引号括起来,例如 '...' 变为 \''...'\'

以上是关于使用 GNU sed 和 GNU find 时如何加速替换?的主要内容,如果未能解决你的问题,请参考以下文章

Mac使用GNU版本的sed

sed 匹配多行,在行首添加字符

如何将 GNU 与 find -exec 并行使用?

gnu并行管道sed - 没有输入文件错误

使用 gnu-find 的退出状态测试文件是不是存在

gnu parallel + sed 编辑 csv 标题和内容