使用上下文标志时是否从grep中排除单词?

使用上下文标志时是否从grep中排除单词?,grep,Grep,是否有某种方法可以从grep结果中删除不需要的行,而不与显示上下文(-a,-B)、着色匹配(--color)或显示文件名和行号(-nH)冲突 例如,考虑对复杂的多文件编译日志进行grepping,以查看针对alpha.o而不是针对beta.o编译的文件。如果我只想要没有任何其他特征的线条,我可以做如下的事情 find -name "make.log" -exec grep 'alpha.o' {} \; | grep -v 'beta.o' 是否有机会将类似的过滤器应用于 find -name

是否有某种方法可以从
grep
结果中删除不需要的行,而不与显示上下文(
-a
-B
)、着色匹配(
--color
)或显示文件名和行号(
-nH
)冲突

例如,考虑对复杂的多文件编译日志进行grepping,以查看针对
alpha.o
而不是针对
beta.o
编译的文件。如果我只想要没有任何其他特征的线条,我可以做如下的事情

find -name "make.log" -exec grep 'alpha.o' {} \; | grep -v 'beta.o'
是否有机会将类似的过滤器应用于

find -name "make.log" -exec grep --color -A 3 -B 3 -nH 'alpha.o' {} \;
最少的工作示例。 这是一个玩具的例子,因为现实世界的例子是一个公司产品。我想不出一个好方法来提供一个成功的大型现实例子

# Reproducible random file.
# -- example.bash --

mkdir -p /tmp/foo
cd /tmp/foo
RANDOM=0 # Seed it.
for ((i=0;i<10000;i++)); do
    printf ' %04x%04x' $RANDOM $RANDOM $RANDOM $RANDOM
    if (($RANDOM % 100 > 1)); then 
        printf ' 0a00%04x' $RANDOM
    else
        printf ' %04x%04x' $RANDOM $RANDOM
    fi
    printf ' %04x%04x' $RANDOM $RANDOM $RANDOM $RANDOM
    printf '\n'
done | split -l 1000 - data.
我注意到有一个以“0a00”开头的列的循环模式。让我们看看是否还有其他有趣的模式

>>> grep -n '\b0a' /tmp/foo/data.* | grep -v '\b0a00'
/tmp/foo/data.aa:607: 21c1631c 09fd779d 37435823 12873910 0aa64882
/tmp/foo/data.aa:759: 1d213f2c 0ac76099 5c0719c5 26c1265c 30db2bc3
/tmp/foo/data.ab:677: 09b2512f 0ac0772e 5e9156f6 6f396505 5e027e02
/tmp/foo/data.ad:102: 1a191fad 582104da 4cdd7c5c 3d624820 0aa863fa
/tmp/foo/data.af:556: 559b7651 0a6c0a34 34612ac1 29567c5c 2f62187f
...
为了便于查看,最好添加彩色化。但由于ansi转义序列,这违反了过滤规则

事情从这里开始变得很奇怪。作为一种解决方法,我们可能会在事件发生后重新添加高亮显示,但它不会使文件/行号列着色

同样,使用
-A
-B
添加上下文也需要付出努力。例如,
grep-n-a3'\b0a'/tmp/foo/data.*grep-v'\b0a00'
将给出不满意的结果,因为它不知道上下文行

同样,文件名和行号部分也可能导致问题。例如,当输出包含文件名时,我们可能希望排除搜索字符串位于行首(
grep-v'^PATTERN'
)的行,这是不容易做到的


将grep结果管道化到
grep-v
,因此很快会导致糟糕的可维护性和过于复杂的结构。

我看到了两种方法:

  • 保留转义序列并将其包含在您的模式中
  • Post突出显示文本
  • 在模式中包括转义序列 下面是一个在这里工作的示例。您可能需要调整匹配的转义序列:

    # Define the coloring reset sequence
    rst=$'\x1b\\\[m\x1b\\\[K'
    grep --color=always -n '\b0a' /tmp/foo/data.* | grep -vE "0a${rst}00"
    
    输出:

    /tmp/foo/data.aa:39:4d633499 398a4f7a 0a935cbd 2c4f2c3a 154f7a91
    /tmp/foo/data.ab:178:0a1300b0 2ad5117e 572b548e 68040659 5dee37bf
    /tmp/foo/data.ab:636:02e05497 0cfe1378 0ab90ea2 36aa7fb2 0ee64bbb
    /tmp/foo/data.ac:369:3e1173bd 0a2b4bb0 075d7b29 53336401 30407990
    /tmp/foo/data.ac:578:00f22d00 0a826912 79b16c04 27ab7fbb 02085f85
    /tmp/foo/data.ac:690:44847461 12384d93 6f35227c 2A1F1F1421 0a68356f
    /tmp/foo/data.ad:27:07443f46 3a59377e 2fb731a6 31996a1e 0aab0e69
    /tmp/foo/data.aj:158:3c90509b 0a5e5803 3e8d50cd 7e89059d 292b723f
    

    事后强调 下面是一个如何使用的示例:

    将此文件保存到langDefs目录(还有改进的余地):

    格雷普·朗

    Description=“Grep”
    数字=[[:-]\d+[:-]]
    关键词={
    {Id=1,
    正则表达式=[[^[^:-]+]],
    },
    {Id=2,
    正则表达式=[[^--$]],
    },
    }
    
    您现在可以执行以下操作:

    grep -n -A3 '\b0a' /tmp/foo/data.* | grep -vE '0a00' | highlight -S grep -O ansi
    

    我发现最简单的方法可能是颠倒逻辑,首先应用排除模式

    例子 例如,对于问题中的示例,可以不使用
    grep-n'\b0a'/tmp/foo/data.*grep-v'\b0a00'

    >>> grep --color=always -nH -v '\b0a00' /tmp/foo/data.* | grep --color '\b0a'
    #                |
    #                 ` Without 'always' color wouldn't be applied 
    #                   when piping the result.
    
    并接收全彩色输出:

    同样的方法适用于
    -A
    -B

    赞成
    • 不需要可能未安装在给定系统上的工具
    对立面
    • 匹配行(
      FILENAME:000:…
      )和上下文行(
      FILENAME-000-…
      )之间的区别丢失
    • 数字/名称前缀使得“行首”模式的grepping仍然很尴尬。与
      ^foo
      不同的是,你必须为
      ^.*?:.*?:foo
      。即使这样,“颜色”解决方案也不能很好地解决这一问题,可以使用中所述的后处理着色来解决。但是,我们又回到了安装附加工具的阶段

    听起来是个不错的问题,投了赞成票。但是,您仍然应该添加一些我们可以处理的示例,添加一些测试数据,我太懒了,无法创建自己的。并且,在提问时,尽量遵守标准questions@Thor增加了一些例子。起初我没有,因为我可以上传的任何东西都是一个玩具示例,与实际应用程序相去甚远。我遇到的所有案例要么在隐私方面存在问题(例如,从Keepass过滤数据),要么属于商业秘密条例,要么太大,无法在这里发布。
    >>> grep --color=always -nH -v '\b0a00' /tmp/foo/data.* | grep --color '\b0a'
    #                |
    #                 ` Without 'always' color wouldn't be applied 
    #                   when piping the result.