使用上下文标志时是否从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
,因此很快会导致糟糕的可维护性和过于复杂的结构。我看到了两种方法:
# 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
>>> grep --color=always -nH -v '\b0a00' /tmp/foo/data.* | grep --color '\b0a'
# |
# ` Without 'always' color wouldn't be applied
# when piping the result.