与使用此 sed 命令的 while 循环相比,GNU Parallel 产生不同的输出
GNU Parallel produces different output compared to while loop with this sed command
我对 GNU Parallel 如何处理输入 sed 就地文件编辑的管道输入感到困惑,我想了解它在做什么(并且这样我才能让它工作!)。
我有两个文件,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 循环行为有什么想法吗?
谢谢!
我知道所有这些并行的东西,但如果你只是想做一些比从 shell 循环调用的 sed 脚本更有效的事情,那么你只需要:
awk 'NR==FNR{a[]=[=10=];next} {print ( in a ? a[] : [=10=])}' f1 f2
如果您觉得这比仅使用显式 tmp 文件更好,可以将 -i 与 GNU awk 结合使用。
是sed没有原地替换的缘故。它所做的是创建一个新文件,然后将其移动到原始文件。
所以您看到的是多个 sed
并行创建一个新文件。当其中一个完成时,它将覆盖原始文件,但是当前 运行 的其他 sed
将看不到它,它们仍在处理原始文件。
因此,如果您使用 -j1
,您将不会遇到此问题。但是你也不会看到加速。
我不确定 GNU Parallel 能否在这方面为您提供帮助。一个解决方案是将 f2 转换成一个大的 sed 脚本。
这里是 Ed Morton 回答的变体。这个变体说明了一种非常有用的技术并且应该(非常轻微)更快,因为它避免了检查 NR==NFR:
awk -v dict=f1 'BEGIN { while (getline < dict) {a[]=[=10=]} } {print ( in a ? a[] : [=10=])}' f2
我对 GNU Parallel 如何处理输入 sed 就地文件编辑的管道输入感到困惑,我想了解它在做什么(并且这样我才能让它工作!)。
我有两个文件,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 循环行为有什么想法吗?
谢谢!
我知道所有这些并行的东西,但如果你只是想做一些比从 shell 循环调用的 sed 脚本更有效的事情,那么你只需要:
awk 'NR==FNR{a[]=[=10=];next} {print ( in a ? a[] : [=10=])}' f1 f2
如果您觉得这比仅使用显式 tmp 文件更好,可以将 -i 与 GNU awk 结合使用。
是sed没有原地替换的缘故。它所做的是创建一个新文件,然后将其移动到原始文件。
所以您看到的是多个 sed
并行创建一个新文件。当其中一个完成时,它将覆盖原始文件,但是当前 运行 的其他 sed
将看不到它,它们仍在处理原始文件。
因此,如果您使用 -j1
,您将不会遇到此问题。但是你也不会看到加速。
我不确定 GNU Parallel 能否在这方面为您提供帮助。一个解决方案是将 f2 转换成一个大的 sed 脚本。
这里是 Ed Morton 回答的变体。这个变体说明了一种非常有用的技术并且应该(非常轻微)更快,因为它避免了检查 NR==NFR:
awk -v dict=f1 'BEGIN { while (getline < dict) {a[]=[=10=]} } {print ( in a ? a[] : [=10=])}' f2