我对GNU并行是如何处理输入到sed内部文件编辑中的管道输入感到困惑,我想了解它在做什么(也是为了让它工作!)。
我有两个文件,f1和f2,如下所示:
f1
a11 a12 a13
a21 a22 a23
...
an1 an2 an3f2
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并行来复制它,如下所示:
cat f1 | parallel --colsep '\t' -q sed -i "s/{1}/& {2} {3}/g" f2它只修改f2中的一小部分条目,而不是while循环。看起来会是这样的:
a41 a42 a43
stuff
...
a91
things
...
a71 a72 a73
words
...那么,对于发生了什么,以及我如何使用GNU并行复制while循环行为,有什么想法吗?
谢谢!
发布于 2015-02-18 20:21:53
这是因为sed没有替换到位。它所做的是创建一个新的文件,然后移动到原始文件。
因此,您看到的是并行的多个sed,每个都创建了一个新文件。当其中一个完成时,它将覆盖原始文件,但是其他正在运行的sed不会看到这一点,它仍然在处理原始文件。
因此,如果您使用-j1,您将不会看到这个问题。但你也不会看到速度加快。
我不确定GNU平行在这里能帮到你。一个解决方案是将f2转换为一个大的sed脚本。
发布于 2015-02-18 20:07:20
但是,如果您只是想做一些比shell循环中调用的sed脚本更有效的事情,那么您所需要的就是:
awk 'NR==FNR{a[$1]=$0;next} {print ($1 in a ? a[$1] : $0)}' f1 f2如果您觉得-i内嵌的GNU比只使用一个显式的tmp文件更好的话,您可以在GNU中使用它。
发布于 2015-03-22 20:19:04
这是埃德·莫顿答案的一个变体。这个变体说明了一种非常有用的技术,并且应该(稍微)快一些,因为它避免了检查NR==NFR:awk -v dict=f1 'BEGIN { while (getline < dict) {a[$1]=$0} } {print ($1 in a ? a[$1] : $0)}' f2。
https://stackoverflow.com/questions/28591994
复制相似问题