为什么并行模式下的 xargs 不能与 grep 一起使用?
Why doesn't xargs in parallel mode work with grep?
cat gg
给予
192
和
cat tmpfilelist
给予
android/app/src/main/res/drawable-mdpi/src_assets_images_alerts_iconnotificationsmartpluggreen.png
android/app/src/main/res/drawable-mdpi/src_assets_images_ic_biggames.png
android/app/src/main/res/drawable-xhdpi/src_assets_images_alerts_iconnotificationsmartpluggreen.png
android/app/src/main/res/drawable-xhdpi/src_assets_images_ic_biggames.png
android/app/src/main/res/drawable-xxhdpi /src_assets_images_alerts_iconnotificationsmartpluggreen.png
android/app/src/main/res/drawable-xxhdpi/src_assets_images_ic_biggames.png
gg
ios/WebRTC.framework/Headers/RTCCallbackLogger.h
ios/WebRTC.framework/Headers/RTCFileLogger.h
ios/WebRTC.framework/Headers/RTCLogging.h
I 运行 xargs 并联模式打开 - 这找不到所需的文本“192”:
cat tmpfilelist | \xargs -P0 -t -I {} \bash -c "\grep -C 2 -H -I -r 192 {}" |& \grep -C 3 "192 gg"
bash -c '\grep -C 2 -H -I -r 192 android/app/src/main/res/drawable-xhdpi/src_assets_images_ic_biggames.png'
bash -c '\grep -C 2 -H -I -r 192 android/app/src/main/res/drawable-xxhdpi/src_assets_images_alerts_iconnotificationsmartpluggreen.png'
bash -c '\grep -C 2 -H -I -r 192 android/app/src/main/res/drawable-xxhdp/src_assets_images_ic_biggames.png'
bash -c '\grep -C 2 -H -I -r 192 gg'
bash -c '\grep -C 2 -H -I -r 192 ios/WebRTC.framework/Headers/RTCCallbackLogger.h'
bash -c '\grep -C 2 -H -I -r 192 ios/WebRTC.framework/Headers/RTCFileLogger.h'
bash -c '\grep -C 2 -H -I -r 192 ios/WebRTC.framework/Headers/RTCLogging.h'
当我禁用并行模式时,它成功地在文件 "gg":
中找到文本“192”
cat tmpfilelist | \xargs -t -I {} \bash -c "\grep -C 2 -H -I -r 192 {}" |& \grep -C 3 "192 gg"
bash -c '\grep -C 2 -H -I -r 192 android/app/src/main/res/drawable-xhdpi/src_assets_images_ic_biggames.png'
bash -c '\grep -C 2 -H -I -r 192 android/app/src/main/res/drawable-xxhdpi/src_assets_images_alerts_iconnotificationsmartpluggreen.png'
bash -c '\grep -C 2 -H -I -r 192 android/app/src/main/res/drawable-xxhdp/src_assets_images_ic_biggames.png'
bash -c '\grep -C 2 -H -I -r 192 gg'
gg:192
bash -c '\grep -C 2 -H -I -r 192 ios/WebRTC.framework/Headers/RTCCallbackLogger.h'
bash -c '\grep -C 2 -H -I -r 192 ios/WebRTC.framework/Headers/RTCFileLogger.h'
为什么并行模式会破坏 grep?还是我哪里弄错了?
非常感谢
确实是并行执行的问题。问题是当您 运行 并行输出时,输出不确定。我创建了一个类似的测试
bash-5.0# ls -alh
total 32K
drwxr-xr-x 9 root root 288 May 20 17:00 .
drwxr-xr-x 1 root root 4.0K May 20 17:11 ..
-rw-r--r-- 1 root root 3 May 20 17:00 a
-rw-r--r-- 1 root root 3 May 20 17:00 b
-rw-r--r-- 1 root root 3 May 20 17:00 c
-rw-r--r-- 1 root root 4 May 20 17:00 d
-rw-r--r-- 1 root root 3 May 20 17:00 e
-rw-r--r-- 1 root root 3 May 20 17:00 f
-rw-r--r-- 1 root root 11 May 20 17:00 files
bash-5.0# tail -n +1 *
==> a <==
192
==> b <==
193
==> c <==
192
==> d <==
195
==> e <==
200
==> f <==
198
==> files <==
a
b
c
d
e
f
现在,如果我们 运行 你的两个命令没有最后一个 grep,输出如下所示
不并联
bash-5.0# cat files | \xargs -t -I {} \bash -c "\grep -C 2 -H -I -r 192 {}"
bash -c \grep -C 2 -H -I -r 192 a
a:192
bash -c \grep -C 2 -H -I -r 192 b
bash -c \grep -C 2 -H -I -r 192 c
c:192
bash -c \grep -C 2 -H -I -r 192 d
bash -c \grep -C 2 -H -I -r 192 e
bash -c \grep -C 2 -H -I -r 192 f
并联
bash-5.0# cat files | \xargs -P4 -t -I {} \bash -c "\grep -C 2 -H -I -r 192 {}"
bash -c \grep -C 2 -H -I -r 192 a
bash -c \grep -C 2 -H -I -r 192 b
bash -c \grep -C 2 -H -I -r 192 c
bash -c \grep -C 2 -H -I -r 192 d
bash -c \grep -C 2 -H -I -r 192 e
a:192
bash -c \grep -C 2 -H -I -r 192 f
c:192
希望您能看到它是如何影响您生产线的输出和订单的。所以你的问题是,当你执行 grep -C 3 192 gg
时,你应该在打印 192 gg
之前得到 3 行,在打印之后得到 3 行,你实际上得到了。
但是 gg:192
稍后打印,因为每个命令在同一个输出终端上并行发送它们的输出
不是答案 - 但指出了可能的问题。
代码在管道中运行两个过滤器
- grep -C 2 -H -I -r 192 文件名
- grep -C 3 "192 gg"
第一行的输出将遵循 'FILENAME:DATA' 格式。在上面的例子中
gg:192
第二个过滤器不会找到模式“192 gg”。
所以问题可能是非并行如何产生任何输出?
简答
您的最终 grep -C 3
请求围绕 192 gg
的 3 行上下文。在并行情况下,这可能不足以找到包含 gg:192
.
的行
详情
在最后的 grep
之前,您的输出将包含许多行,例如:
bash -c \grep -C 2 -H -I -r 192 <filename>
在 xargs
启动每个 bash -c ...
命令之前回显到 stderr,行
gg:192
当相关 bash -c ...
命令(即涉及文件 gg
的命令)找到匹配项时, 被回显到标准输出。
在并行情况下,通过管道传输到最终 grep
的整个输出(一旦使用 |&
组合了 stderr 和 stdout)可能看起来像这样,我已经替换了为简洁起见的其他文件名:
bash -c \grep -C 2 -H -I -r 192 some_file
bash -c \grep -C 2 -H -I -r 192 some_other_file
bash -c \grep -C 2 -H -I -r 192 another_file
bash -c \grep -C 2 -H -I -r 192 gg
bash -c \grep -C 2 -H -I -r 192 and_another_file
bash -c \grep -C 2 -H -I -r 192 yet_another_file
gg:192
bash -c \grep -C 2 -H -I -r 192 and_yet_another_file
在此示例中,涉及 and_another_file
和 yet_another_file
的 bash -c ...
命令被启动 在 涉及 gg
的命令之后已启动,但在涉及 gg
的那个写入其输出之前(或至少在刷新与该输出关联的任何 stdio 缓冲区之前),因此它们出现在包含 192 gg
和 gg:192
的行之间.
包含 192 gg
和 gg:192
的行之间的此类中间行的数量(在本例中为 2)将取决于时间和在该任务之后启动的其他并行任务的数量涉及 gg
。这会有所不同,例如,如果您插入了 sleep
语句(例如 ... \bash -c "sleep 1; \grep -C ...
),那么往往会有更多这样的行。在任何情况下,您都将其通过管道传输到 grep -C 3
以提取 3 行上下文。如果恰好有少于 3 个中间行,那么这个 grep -C
将找到包含 gg:192
的行,但如果有 3 个或更多,那么它将超出请求的上下文量并且不会出现在最终输出中。
然而,在串行情况下,gg:192
行保证始终紧跟在 192 gg
行之后,如下所示:
bash -c \grep -C 2 -H -I -r 192 some_file
bash -c \grep -C 2 -H -I -r 192 some_other_file
bash -c \grep -C 2 -H -I -r 192 another_file
bash -c \grep -C 2 -H -I -r 192 gg
gg:192
bash -c \grep -C 2 -H -I -r 192 and_another_file
bash -c \grep -C 2 -H -I -r 192 yet_another_file
bash -c \grep -C 2 -H -I -r 192 and_yet_another_file
所以它总是在 3 行上下文中。
cat gg
给予
192
和
cat tmpfilelist
给予
android/app/src/main/res/drawable-mdpi/src_assets_images_alerts_iconnotificationsmartpluggreen.png
android/app/src/main/res/drawable-mdpi/src_assets_images_ic_biggames.png
android/app/src/main/res/drawable-xhdpi/src_assets_images_alerts_iconnotificationsmartpluggreen.png
android/app/src/main/res/drawable-xhdpi/src_assets_images_ic_biggames.png
android/app/src/main/res/drawable-xxhdpi /src_assets_images_alerts_iconnotificationsmartpluggreen.png
android/app/src/main/res/drawable-xxhdpi/src_assets_images_ic_biggames.png
gg
ios/WebRTC.framework/Headers/RTCCallbackLogger.h
ios/WebRTC.framework/Headers/RTCFileLogger.h
ios/WebRTC.framework/Headers/RTCLogging.h
I 运行 xargs 并联模式打开 - 这找不到所需的文本“192”:
cat tmpfilelist | \xargs -P0 -t -I {} \bash -c "\grep -C 2 -H -I -r 192 {}" |& \grep -C 3 "192 gg"
bash -c '\grep -C 2 -H -I -r 192 android/app/src/main/res/drawable-xhdpi/src_assets_images_ic_biggames.png'
bash -c '\grep -C 2 -H -I -r 192 android/app/src/main/res/drawable-xxhdpi/src_assets_images_alerts_iconnotificationsmartpluggreen.png'
bash -c '\grep -C 2 -H -I -r 192 android/app/src/main/res/drawable-xxhdp/src_assets_images_ic_biggames.png'
bash -c '\grep -C 2 -H -I -r 192 gg'
bash -c '\grep -C 2 -H -I -r 192 ios/WebRTC.framework/Headers/RTCCallbackLogger.h'
bash -c '\grep -C 2 -H -I -r 192 ios/WebRTC.framework/Headers/RTCFileLogger.h'
bash -c '\grep -C 2 -H -I -r 192 ios/WebRTC.framework/Headers/RTCLogging.h'
当我禁用并行模式时,它成功地在文件 "gg":
中找到文本“192”cat tmpfilelist | \xargs -t -I {} \bash -c "\grep -C 2 -H -I -r 192 {}" |& \grep -C 3 "192 gg"
bash -c '\grep -C 2 -H -I -r 192 android/app/src/main/res/drawable-xhdpi/src_assets_images_ic_biggames.png'
bash -c '\grep -C 2 -H -I -r 192 android/app/src/main/res/drawable-xxhdpi/src_assets_images_alerts_iconnotificationsmartpluggreen.png'
bash -c '\grep -C 2 -H -I -r 192 android/app/src/main/res/drawable-xxhdp/src_assets_images_ic_biggames.png'
bash -c '\grep -C 2 -H -I -r 192 gg'
gg:192
bash -c '\grep -C 2 -H -I -r 192 ios/WebRTC.framework/Headers/RTCCallbackLogger.h'
bash -c '\grep -C 2 -H -I -r 192 ios/WebRTC.framework/Headers/RTCFileLogger.h'
为什么并行模式会破坏 grep?还是我哪里弄错了?
非常感谢
确实是并行执行的问题。问题是当您 运行 并行输出时,输出不确定。我创建了一个类似的测试
bash-5.0# ls -alh
total 32K
drwxr-xr-x 9 root root 288 May 20 17:00 .
drwxr-xr-x 1 root root 4.0K May 20 17:11 ..
-rw-r--r-- 1 root root 3 May 20 17:00 a
-rw-r--r-- 1 root root 3 May 20 17:00 b
-rw-r--r-- 1 root root 3 May 20 17:00 c
-rw-r--r-- 1 root root 4 May 20 17:00 d
-rw-r--r-- 1 root root 3 May 20 17:00 e
-rw-r--r-- 1 root root 3 May 20 17:00 f
-rw-r--r-- 1 root root 11 May 20 17:00 files
bash-5.0# tail -n +1 *
==> a <==
192
==> b <==
193
==> c <==
192
==> d <==
195
==> e <==
200
==> f <==
198
==> files <==
a
b
c
d
e
f
现在,如果我们 运行 你的两个命令没有最后一个 grep,输出如下所示
不并联
bash-5.0# cat files | \xargs -t -I {} \bash -c "\grep -C 2 -H -I -r 192 {}"
bash -c \grep -C 2 -H -I -r 192 a
a:192
bash -c \grep -C 2 -H -I -r 192 b
bash -c \grep -C 2 -H -I -r 192 c
c:192
bash -c \grep -C 2 -H -I -r 192 d
bash -c \grep -C 2 -H -I -r 192 e
bash -c \grep -C 2 -H -I -r 192 f
并联
bash-5.0# cat files | \xargs -P4 -t -I {} \bash -c "\grep -C 2 -H -I -r 192 {}"
bash -c \grep -C 2 -H -I -r 192 a
bash -c \grep -C 2 -H -I -r 192 b
bash -c \grep -C 2 -H -I -r 192 c
bash -c \grep -C 2 -H -I -r 192 d
bash -c \grep -C 2 -H -I -r 192 e
a:192
bash -c \grep -C 2 -H -I -r 192 f
c:192
希望您能看到它是如何影响您生产线的输出和订单的。所以你的问题是,当你执行 grep -C 3 192 gg
时,你应该在打印 192 gg
之前得到 3 行,在打印之后得到 3 行,你实际上得到了。
但是 gg:192
稍后打印,因为每个命令在同一个输出终端上并行发送它们的输出
不是答案 - 但指出了可能的问题。
代码在管道中运行两个过滤器
- grep -C 2 -H -I -r 192 文件名
- grep -C 3 "192 gg"
第一行的输出将遵循 'FILENAME:DATA' 格式。在上面的例子中
gg:192
第二个过滤器不会找到模式“192 gg”。
所以问题可能是非并行如何产生任何输出?
简答
您的最终 grep -C 3
请求围绕 192 gg
的 3 行上下文。在并行情况下,这可能不足以找到包含 gg:192
.
详情
在最后的 grep
之前,您的输出将包含许多行,例如:
bash -c \grep -C 2 -H -I -r 192 <filename>
在 xargs
启动每个 bash -c ...
命令之前回显到 stderr,行
gg:192
当相关 bash -c ...
命令(即涉及文件 gg
的命令)找到匹配项时,被回显到标准输出。
在并行情况下,通过管道传输到最终 grep
的整个输出(一旦使用 |&
组合了 stderr 和 stdout)可能看起来像这样,我已经替换了为简洁起见的其他文件名:
bash -c \grep -C 2 -H -I -r 192 some_file
bash -c \grep -C 2 -H -I -r 192 some_other_file
bash -c \grep -C 2 -H -I -r 192 another_file
bash -c \grep -C 2 -H -I -r 192 gg
bash -c \grep -C 2 -H -I -r 192 and_another_file
bash -c \grep -C 2 -H -I -r 192 yet_another_file
gg:192
bash -c \grep -C 2 -H -I -r 192 and_yet_another_file
在此示例中,涉及 and_another_file
和 yet_another_file
的 bash -c ...
命令被启动 在 涉及 gg
的命令之后已启动,但在涉及 gg
的那个写入其输出之前(或至少在刷新与该输出关联的任何 stdio 缓冲区之前),因此它们出现在包含 192 gg
和 gg:192
的行之间.
包含 192 gg
和 gg:192
的行之间的此类中间行的数量(在本例中为 2)将取决于时间和在该任务之后启动的其他并行任务的数量涉及 gg
。这会有所不同,例如,如果您插入了 sleep
语句(例如 ... \bash -c "sleep 1; \grep -C ...
),那么往往会有更多这样的行。在任何情况下,您都将其通过管道传输到 grep -C 3
以提取 3 行上下文。如果恰好有少于 3 个中间行,那么这个 grep -C
将找到包含 gg:192
的行,但如果有 3 个或更多,那么它将超出请求的上下文量并且不会出现在最终输出中。
然而,在串行情况下,gg:192
行保证始终紧跟在 192 gg
行之后,如下所示:
bash -c \grep -C 2 -H -I -r 192 some_file
bash -c \grep -C 2 -H -I -r 192 some_other_file
bash -c \grep -C 2 -H -I -r 192 another_file
bash -c \grep -C 2 -H -I -r 192 gg
gg:192
bash -c \grep -C 2 -H -I -r 192 and_another_file
bash -c \grep -C 2 -H -I -r 192 yet_another_file
bash -c \grep -C 2 -H -I -r 192 and_yet_another_file
所以它总是在 3 行上下文中。