【问题标题】:Why doesn't xargs in parallel mode work with grep?为什么并行模式下的 xargs 不能与 grep 一起使用?
【发布时间】:2020-05-27 15:28:20
【问题描述】:
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  

我在并行模式下运行 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 的任何原因?还是我在某个地方犯了错误?

非常感谢

【问题讨论】:

  • 有人知道吗?
  • 你能澄清几点吗 (1) 为什么在二进制文件上使用 grep (2) 为什么将 'grep` 包含在 'bash ...` 中 (3) 所需的输出是什么(匹配列表文件?)?
  • @dash-o (1) 这是无意的 (2) 在 bash 命令中包装命令允许 xargs 执行多个功能。 (3)查看“当我禁用并行模式时,它成功在文件“gg”中找到文本“192”之后的sn-p:

标签: linux xargs


【解决方案1】:

问题确实是由于并行执行造成的。问题是当您并行运行时输出不是确定性的。我创建了一个类似的测试

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 会在稍后打印,因为每个命令在同一个输出终端上并行发送它们的输出

【讨论】:

    【解决方案2】:

    不是答案 - 而是指出可能的问题。

    代码在管道中运行两个过滤器

    • grep -C 2 -H -I -r 192 文件名
    • grep -C 3 "192 gg"

    第一行的输出将遵循“文件名:数据”格式。在上面的例子中

    gg:192
    

    第二个过滤器不会找到模式“192 gg”。

    所以问题可能是非并行如何产生任何输出?

    【讨论】:

      【解决方案3】:

      简答

      您的最终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 的整个输出(一旦使用 |&amp; 组合 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_fileyet_another_filebash -c ... 命令在涉及gg 的命令启动之后 启动,但在涉及gg 的命令写入输出之前(或至少,在刷新与该输出关联的任何 stdio 缓冲区之前),因此它们出现在包含 192 gggg:192 的行之间。

      包含192 gggg: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 行上下文中。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-01-09
        • 1970-01-01
        • 2014-03-11
        • 2018-07-30
        • 1970-01-01
        • 2012-04-05
        • 2014-06-18
        相关资源
        最近更新 更多