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

4

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

我需要将字符串 "wavelength;" 替换为 "wavelength_bc;",因此我尝试了以下两种方法:

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

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

很不幸,上述命令需要非常长的时间才能完成(超过1小时)。

我想知道如何利用我的计算机上的核心数量(8个)加速上述命令?

我考虑使用带有-P标志的xargs。但我担心这样会破坏文件;所以我不知道这是否安全?

总之:

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

谢谢


1
是的,xargs -P 应该是完全安全的使用。 - anubhava
1
@anubhava:谢谢!我现在正在尝试。你能写一个答案吗? - Iyach tharwa nambarek
即使在输入到 xargs -P sed -i [...] 中的文件列表中出现了重复,它也应该是安全的(但效率较低),但是当输入来自 find 的输出时将不会出现这种重复。 - John Bollinger
2个回答

5

xargs -P 是安全的使用方式,但是你需要使用 -print0 选项查找并将其传输到 xargs -0 中来处理带有空格或通配符的文件名:

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

xargs 命令中使用 -P 0 选项将以并行模式运行。它将利用您的 CPU,尽可能地运行多个进程。

2
选项 -P 8 将始终并行运行 8 个作业,但选项 -P 0 将检查您的处理器,并尽可能地运行多个并行作业以适应该 CPU。请注意,由于您拥有 8 核心处理器,因此选项 -P 0 实际上与 -P 8 相同。 - anubhava
1
使用该命令后,程序执行完成所需时间为:实际时间 43分15.117秒、用户时间 39分54.227秒、系统时间 53分27.121秒 - Iyach tharwa nambarek
好的,这是一些改进。 - anubhava

2
这可能适用于你(GNU sed和parallel):
find . -type f | parallel -q sed -i 's/wavelength;/wavelength_bc;/g' {}

GNU并行处理将同时运行与机器核心数量相同的作业。

更复杂的用法可以涉及远程服务器和文件传输,请参见这里这里的速查表。


你必须转义分号才能使其正常工作! - s.ouchene
@s.ouchene 哎呀!替代方案是使用并行的 -q 选项或者像这样用单引号包裹 '...' 变成 \''...'\' - potong

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接