有没有什么方法可以使用grep
单一条件搜索以任何顺序匹配多个模式的条目?
如图所示如何使用多个 AND 模式运行 grep?对于我可以使用的多种模式
grep -e 'foo.*bar' -e 'bar.*foo'
但我必须在这里写 2 个条件,3 个模式的 6 个条件等等...如果可能的话,我想写单个条件。要以任何顺序查找模式,您可以建议使用:
grep -e 'foo' | grep -e 'bar' # at least i do not retype patterns here
这会起作用,但我希望看到彩色输出,并且仅在这种情况下酒吧将突出显示。
我想写的条件很简单
awk '/foo/ && /bar/'
如果可能的话grep
(awk 不会突出显示结果,我怀疑它可以轻松完成)。
agrep
也许可以做我想做的事,但我想知道 ubuntu 12.04 上的默认 grep (2.10-1) 是否可以做到这一点。
答案1
如果您的版本grep
支持 PCRE(GNUgrep
使用-P
或--perl-regexp
选项执行此操作),您可以使用前瞻以任何顺序匹配多个单词:
grep -P '(?=.*?word1)(?=.*?word2)(?=.*?word3)^.*$'
不过,这不会突出显示这些词。前瞻是零长度断言,它们不是匹配序列的一部分。
我认为你的管道解决方案应该适用于此。默认情况下,grep
仅在输出到达终端时才对输出进行着色,因此只有管道中的最后一个命令会突出显示,但您可以使用--color=always
.
grep --color=always foo | grep --color=always bar
答案2
基于旧答案的新命令
#!/bin/bash
# Build search pipeline
n=$#
SEARCH=""
while [ $n -gt 0 ]; do
if [ -n "$SEARCH" ]; then
SEARCH="|${SEARCH}"
fi
SEARCH="grep --color=always '${!n}'${SEARCH}"
n=$[ $n - 1 ]
done
# Execute all greps in sequence
/bin/bash -c "${SEARCH}"
所以,根据要求:
我想写的条件很简单
awk '/foo/ && /bar/'
yagrep SEARCH grep color < /usr/local/bin/yagrep
搜索= =grep--颜色=总是'${!n}'${搜索}”
旧答案
一个复杂的选项是生成模式的所有排列,将它们提供给grep
正则表达式编译器并希望生成合理优化的搜索树。
但即使模式数量很少,比如 6 个,排列也将是 6!或 720。这会导致命令行很尴尬。
但看来你似乎与管道没有任何争执,grep
除了
这会起作用,但我想看到彩色输出
然后,前提是:
- 图案不重叠
- 模式不包含术语控制字符
一种可接受的解决方案是通过管道传输多个grep
s,每个 s 具有一种模式,按照可能性递增的顺序,从而最大限度地减少负载。
然后为了确保着色有效,您必须强制grep
执行相信它的标准输出是一个终端使用faketerm
或以其他方式,或者如果可用(应该是),您可以使用以下--color=always
选项:
cat file | grep --color=always pattern1 \
| grep --color=always pattern2 \
...
| grep --color=always patternN
(一个不错的做法是将grep
s 包装成单个字符串以由子 shell 执行,并使用 eg 以编程方式生成字符串sed
)。
答案3
您可以使用以下命令对输出进行着色sed
sed -n "/foo/{/bar/s/foo\|bar/\x1b[1;31m&\x1b[m/gp}"
答案4
您可以使用单个基于 OR 的正则表达式来完成此操作。给定文件内容:
This is my file
It has many words
There are also many chars
以下 grep 命令将突出显示单个参数中的“my”和“There”:
grep -P -e '(there|my)' testfile
只需用|
(管道)分隔每个正则表达式模式即可表示 OR。