基于旧答案的新命令

基于旧答案的新命令

有没有什么方法可以使用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除了

这会起作用,但我想看到彩色输出

然后,前提是:

  • 图案不重叠
  • 模式不包含术语控制字符

一种可接受的解决方案是通过管道传输多个greps,每个 s 具有一种模式,按照可能性递增的顺序,从而最大限度地减少负载。

然后为了确保着色有效,您必须强制grep执行相信它的标准输出是一个终端使用faketerm或以其他方式,或者如果可用(应该是),您可以使用以下--color=always选项:

cat file | grep --color=always pattern1 \
         | grep --color=always pattern2 \
         ...
         | grep --color=always patternN 

(一个不错的做法是将greps 包装成单个字符串以由子 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。

相关内容