sed 与并行 –jobs 选项的正确用法是什么?
parallel -a input --colsep ' ' --jobs 100 -I {} sed -i 's/{1}/{2}/g' file
input 是一个由空格分隔的文件,其中第一列是模式,第二列是替换。
问题是,在我运行命令后,并非所有模式都在file. 然后我再次运行相同的命令,替换了更多模式,但仍然不是全部。但是,如果我将--jobs100更改为--jobs 1,它将按预期工作(但速度要慢得多)。
我的命令中是否缺少必要的参数?
回答
听起来更像是你有竞争条件。如果您有多个sed进程写入文件,则一个进程获胜,其他进程失败。
无论如何,让多个进程处理同一个文件是非常不理想的;只需生成一个sed脚本,然后运行一次。或者,如果您真的想要并行化,请将输入文件分成更小的部分,sed并行运行生成的脚本,然后在完成后将它们连接回去。
当您的任务受 CPU 限制时,并行处理会有所帮助,但这是 I/O 限制;您只是通过让多个进程争夺对磁盘字节的访问权而造成拥塞,然后在这种情况下还争夺对同一文件的写访问权。
有很多关于如何生成sed脚本的例子;这是一个快速而肮脏的方法,但是它在某些sed -f -不从标准输入读取脚本的平台上不起作用。
sed 's%^\([^ ]*\) \([^ ]*\)$%s/\1/\2/g%' input |
sed -f - file >temp # or sed -f - -i file
我省略了该-i选项,以便您可以在继续前进并将其部署到生产中之前检查这是否符合您的要求。注释掉的版本是您在确信这确实满足您的要求后将使用的版本。
仍然存在替换优先级的问题。如果你s/a/b/和s/b/c/然后做你想要有效s/a/c/,还是相反?如果你有s/abc/x/和s/abcdef/y/,应该abcdef总是变成y,或者是xdef你所期望的?一个常见的技巧是按长度对替换进行排序,以便较长的总是在较短的之前执行;那么至少你知道会发生什么。