首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >与使用sed命令的while循环相比,GNU并行产生不同的输出。

与使用sed命令的while循环相比,GNU并行产生不同的输出。
EN

Stack Overflow用户
提问于 2015-02-18 19:16:04
回答 3查看 168关注 0票数 1

我对GNU并行是如何处理输入到sed内部文件编辑中的管道输入感到困惑,我想了解它在做什么(也是为了让它工作!)。

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

f1

代码语言:javascript
复制
a11    a12    a13
a21    a22    a23
...
an1    an2    an3

f2

代码语言:javascript
复制
a41
stuff
...
a91
stuff
...

我要做的是将第二列和第三列中的元素从f1连接到f2中的每个对应元素(第一列),这样f2看起来就像:

代码语言:javascript
复制
a41 a42 a43
stuff
...
a91 a92 a93
things
...

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

代码语言:javascript
复制
while IFS=$'\t' read -r e1 e2 e3; do sed -i "s/$e1/& $e2 $e3/g" f2 ; done < f1

我试着用GNU并行来复制它,如下所示:

代码语言:javascript
复制
cat f1 | parallel --colsep '\t' -q sed -i "s/{1}/& {2} {3}/g" f2

它只修改f2中的一小部分条目,而不是while循环。看起来会是这样的:

代码语言:javascript
复制
a41 a42 a43
stuff
...
a91
things
...
a71 a72 a73
words
...

那么,对于发生了什么,以及我如何使用GNU并行复制while循环行为,有什么想法吗?

谢谢!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-02-18 20:21:53

这是因为sed没有替换到位。它所做的是创建一个新的文件,然后移动到原始文件。

因此,您看到的是并行的多个sed,每个都创建了一个新文件。当其中一个完成时,它将覆盖原始文件,但是其他正在运行的sed不会看到这一点,它仍然在处理原始文件。

因此,如果您使用-j1,您将不会看到这个问题。但你也不会看到速度加快。

我不确定GNU平行在这里能帮到你。一个解决方案是将f2转换为一个大的sed脚本。

票数 1
EN

Stack Overflow用户

发布于 2015-02-18 20:07:20

但是,如果您只是想做一些比shell循环中调用的sed脚本更有效的事情,那么您所需要的就是:

代码语言:javascript
复制
awk 'NR==FNR{a[$1]=$0;next} {print ($1 in a ? a[$1] : $0)}' f1 f2

如果您觉得-i内嵌的GNU比只使用一个显式的tmp文件更好的话,您可以在GNU中使用它。

票数 1
EN

Stack Overflow用户

发布于 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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28591994

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档