Shell 如何grep并匹配行的第一个匹配项?
鉴于以下内容:Shell 如何grep并匹配行的第一个匹配项?,shell,grep,Shell,Grep,鉴于以下内容: title="Bar=1; Fizz=2; Foo_Bar=3;" 我想匹配第一个出现的Bar值,即1。我也不想依赖这个词的深度(就像前面的双引号),因为这个模式可以在中间。 以下是我的尝试: $ grep -o -m1 'Bar=[ ./0-9a-zA-Z_-]\+' input.txt Bar=1 Bar=3 我使用了-m/--max count,它假设在num匹配后停止读取文件,但它不起作用。为什么此选项不能按预期工作 我可以混合使用head-n1,但我想知道是否有可能
title="Bar=1; Fizz=2; Foo_Bar=3;"
我想匹配第一个出现的Bar
值,即1
。我也不想依赖这个词的深度(就像前面的双引号),因为这个模式可以在中间。
以下是我的尝试:
$ grep -o -m1 'Bar=[ ./0-9a-zA-Z_-]\+' input.txt
Bar=1
Bar=3
我使用了-m
/--max count
,它假设在num匹配后停止读取文件,但它不起作用。为什么此选项不能按预期工作
我可以混合使用head-n1
,但我想知道是否有可能用grep
实现这一点?grep
是面向行的,所以在使用-m
[1]时,它显然会按行计算匹配项
-即使在该行中找到多个匹配项(并使用-o
单独输出)
虽然我不知道如何单独使用grep
解决问题(GNUgrep
的-p
选项除外-请参见),awk
可以做到(以便携方式):
$awk-F'Bar=|“”{print$2}'在gnu-grep
中使用基于perl的正则表达式风格,您可以使用:
grep -oP '^(.(?!Bar=\d+))*Bar=\d+' <<< "Bar=1; Fizz=2; Foo_Bar=3;"
Bar=1
您可以使用grep-p
(假设您在gnu grep上)和正向前瞻((?=.*Bar)
)在grep中实现这一点:
echo "Bar=1; Fizz=2; Foo_Bar=3;" | grep -oP -m 1 'Bar=[ ./0-9a-zA-Z_-]+(?=.*Bar)'
首先使用grep使行以Bar开头,然后在行的开头获取Bar:
grep -o "Bar=.*" input.txt | grep -o -m1 "^Bar=[ ./0-9a-zA-Z_-]\+"
当您有一个大文件时,您可以使用
grep -o -m1 "Bar=.*" input.txt | grep -o -m1 "^Bar=[ ./0-9a-zA-Z_-]\+"
虽然你的答案可能比@anubhava的答案更容易掌握,但它有一个明显的缺点,那就是在包含Bar=
的行中只查找一次匹配项。grep-o-m1'Bar=[./0-9a-zA-Z-]\+'input.txt | head-n1
,OP自己也提到了这一可能性,从概念上讲要简单得多(而且可能更高效、更快,尽管这在实践中可能并不重要)。然而,更重要的是,OP希望通过一次grep
调用来解决这个问题;我非常肯定,“[…]通过grep
可以实现这一点吗?”他并非有意暗示多次调用grep
是一个可接受的解决方案。@mklement0我大部分同意。当OP在这里评论说他确实不是在寻找(缓慢而复杂的)双重grep时,我将删除我的答案。
grep -o "Bar=.*" input.txt | grep -o -m1 "^Bar=[ ./0-9a-zA-Z_-]\+"
grep -o -m1 "Bar=.*" input.txt | grep -o -m1 "^Bar=[ ./0-9a-zA-Z_-]\+"