与使用此sed命令的while循环相比,GNU Parallel产生不同的输出

时间:2015-02-18 19:16:05

标签: bash sed while-loop parallel-processing gnu-parallel

我对GNU Parallel如何处理输入到sed inplace文件编辑中的管道输入感到困惑,我想知道它在做什么(也是为了让我能够得到它工作!)。

我有两个文件,f1和f2,如下所示:

F1

a11    a12    a13
a21    a22    a23
...
an1    an2    an3

F2

a41
stuff
...
a91
stuff
...

我想要做的是将第二列和第三列中的元素从 f1 连接到 f2 , f2 如下:

a41 a42 a43
stuff
...
a91 a92 a93
things
...

一个简单的while循环完成工作:

while IFS=$'\t' read -r e1 e2 e3; do sed -i "s/$e1/& $e2 $e3/g" f2 ; done < f1

我尝试使用GNU Parallel来复制它,如下所示:

cat f1 | parallel --colsep '\t' -q sed -i "s/{1}/& {2} {3}/g" f2

与while循环相比,仅修改 f2 中的一小部分条目。它看起来像这样:

a41 a42 a43
stuff
...
a91
things
...
a71 a72 a73
words
...

那么,关于发生了什么的想法,以及如何使用GNU Parallel复制while循环行为?

谢谢!

3 个答案:

答案 0 :(得分:1)

关于所有并行内容的idk但如果你只是想尝试做一些比从shell循环中调用的sed脚本更有效的东西,那么你需要的只是:

awk 'NR==FNR{a[$1]=$0;next} {print ($1 in a ? a[$1] : $0)}' f1 f2

如果您认为这比仅使用显式tmp文件更好,则可以使用-i inplace with GNU awk。

答案 1 :(得分:1)

这是因为没有替换到位。它的作用是创建一个新文件,然后将其移动到原始文件。

所以你看到的是并行多个sed,每个都创建一个新文件。当其中一个完成时,它将覆盖原始文件,但当前正在运行的其他sed将无法查看原始文件。

因此,如果您使用-j1,则不会看到此问题。但你也不会看到加速。

我不确定GNU Parallel可以在这里帮助你。解决方案是将f2转换为大型sed脚本。

答案 2 :(得分:0)

以下是Ed Morton答案的变体。这个变体说明了一个非常有用的技术,应该(非常轻微)更快,因为它避免检查NR == NFR: awk -v dict=f1 'BEGIN { while (getline < dict) {a[$1]=$0} } {print ($1 in a ? a[$1] : $0)}' f2