您不能使用 来执行此操作grep
,但您可以简单地计算匹配数。我不知道grep
您正在使用什么 shell、什么或什么操作系统,但这里有一个可以执行此操作的 bash 函数的示例:
maxOne() (\n pattern="$1"\n file="$2"\n IFS=$\'\\n\'\n set -f\n\n results=( $(grep -m2 -- "$pattern" "$file") )\n if [ "${#results[@]}" -eq 1 ]; then\n printf -- \'%s\\n\' "${results[@]}"\n return 0\n else\n return 1\n fi\n)\n
Run Code Online (Sandbox Code Playgroud)\n将这些行添加到您的文件中~/.bashrc
,或者只是将它们粘贴到正在运行的 bash 会话的终端中,然后您可以执行以下操作:
maxOne foo file\n
Run Code Online (Sandbox Code Playgroud)\n要foo
在 中搜索file
。请注意,-m
此处使用的选项(最大结果)是为了提高grep
在两场比赛后退出的效率,并非所有版本都支持,grep
因此如果它给您带来错误,只需将其删除即可。这不是必需的,它只是加快速度。
重要提示:这不适用于多行搜索字符串,grep -z
如果您grep
支持的话,您可以使用多行搜索字符串。如果您需要能够处理多行搜索模式,则需要不同的方法。此外,这不适用于匹配空行的模式(例如grep \'^$\' file
)。St\xc3\xa9phane\ 的解决方案将处理空行,因此如果这是一个问题,这将是一个更好的选择。与我不同的是,他还可以处理多个文件,这是一个很好的福利。
你可以这样做:
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 "$@"
)
Run Code Online (Sandbox Code Playgroud)
再unique_egrep pattern *.txt
比如。
这里使用-e 'code' -E /dev/null
(代替'code'
)技巧来处理任意文件路径。
所有-e
、-E
、BEGINFILE
和都是 GNU 扩展(尽管现在也在许多其他实现中找到)ENDFILE
。nextfile
nextfile