Grep 在多个匹配上失败

Grep 在多个匹配上失败

我想 grep 一种搜索模式,但只有在只有一个唯一匹配项时才会成功(并输出匹配行)。如果两行匹配,grep 应该失败或不输出任何内容。

答案1

您不能使用 来执行此操作grep,但您可以简单地计算匹配数。我不知道grep您使用的是什么 shell、什么或什么操作系统,但这里有一个可以执行此操作的 bash 函数的示例:

maxOne() (
    pattern="$1"
    file="$2"
    IFS=$'\n'
    set -f

    results=( $(grep -m2 -- "$pattern" "$file") )
    if [ "${#results[@]}" -eq 1 ]; then
        printf -- '%s\n' "${results[@]}"
        return 0
    else
        return 1
    fi
)

将这些行添加到您的文件中~/.bashrc,或者只是将它们粘贴到正在运行的 bash 会话的终端中,然后您可以执行以下操作:

maxOne foo file

foo要在 中搜索file。请注意,-m此处使用的选项(最大结果)是为了提高grep在两场比赛后退出的效率,并非所有版本都支持,grep因此如果它给您一个错误,只需将其删除。这不是必需的,它只是加快速度。

重要的:这不适用于多行搜索字符串,grep -z如果您grep支持的话,您可以使用多行搜索字符串。如果您需要能够处理多行搜索模式,则需要不同的方法。此外,这不适用于匹配空行的模式(例如grep '^$' file)。斯特凡的解决方案将处理空行,因此如果这是一个问题,这将是一个更好的选择。与我不同的是,他还可以处理多个文件,这是一个很好的福利。

答案2

你可以这样做:

unique_egrep() (
  export ERE="$1"; shift
  exec gawk -e '
    BEGIN               {ret = 1}
    BEGINFILE           {n = 0}
    $0 ~ ENVIRON["ERE"] {if (n++) nextfile; found = $0}
    ENDFILE             {if (n == 1) {print FILENAME":"found; ret = 0}}
    END                 {exit ret}' -E /dev/null "$@"
)

unique_egrep pattern *.txt比如。

这里使用-e 'code' -E /dev/null(代替'code')技巧能够处理任意文件路径。

所有-e-EBEGINFILEENDFILE都是nextfileGNU 扩展(尽管nextfile现在也在许多其他实现中找到)。

相关内容