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
我在开启parralel模式的情况下运行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'
当我禁用parralel模式时,它成功地在文件 "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
在打印之前,你应该得到3行的信息 192 gg
和3后,其实你确实得到了。
但是 gg:192
被打印出来,因为每条命令都在同一个输出终端上并行发送它们的输出。
不是答案--但指出了可能的问题。
该代码在管道中运行两个过滤器
第一行的输出将遵循'FILENAME:DATA'的格式。在上面的例子中
gg:192
第二个过滤器是找不到'192 gg'这个模式的。
所以问题可能是,非并行如何产生任何输出?
您的最终 grep -C 3
请求3行上下文,围绕 192 gg
. 在平行的情况下,这可能或可能不足以找到包含有 gg:192
.
在决赛前 grep
,你的输出将由一些行组成,比如说。
bash -c \grep -C 2 -H -I -r 192 <filename>
这几行会被回传到stderr,正好在 xargs
各自 bash -c ...
命令,以及该行的
gg:192
的时候,会被回传到stdout。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
在这个例子中 bash -c ...
涉及 and_another_file
和 yet_another_file
启动的次数 之后 牵涉 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行的上下文中。