仅显示grep命令的第n个匹配项

52
onefish
onechicken
twofish
twochicken
twocows
threechicken

如果我想要使用grep查找包含“two”的行,但我只想要第二个匹配。因此,我希望结果是“twochicken”。

7个回答

44
grep -m2 "two" in-file.txt | tail -n1

停在第二次匹配后,然后取出打印的第二行。

1
如果程序不能按预期执行,那么它可能无法达到预期的结果。如果有两个以上的匹配项,则会输出多行... - poncha
3
尾部应该是:tail -n1 - Thor
1
@poncha:真的吗?grep -m2 确保只有两个匹配项。不过我还是改了,虽然我认为之前也没问题。 - John Zwinck
1
这是一个非常糟糕的答案,因为它不能处理多行匹配(即与 -A-B 结合使用)。然而,其他任何替代方案也都无法处理多行匹配。 - Chiarcos
多行结果的一个可能解决方案在https://superuser.com/questions/1086675/using-grep-how-do-i-show-the-nth-occurence-of-a-pattern中描述。 - Chiarcos

36

试试这个:

awk '/two/{i++}i==2' file

使用您的数据:

kent$  echo "onefish
onechicken
twofish
twochicken
twocows
threechicken"|awk '/two/{i++}i==2'
twochicken

注意: 如果你的文件很大,执行以下操作:

awk '/two/{i++}i==2{print; exit}' file

1
第二个选项无论文件大小都更优秀,不是吗? - poncha
1
有没有办法在第n次出现单词时停止?我的意思是,如果“单词”在一行中重复多次? - anishsane
有没有一种方法可以将“搜索模式”和出现次数“N”作为字符串传递? - rambalachandran
1
awk -v p="two" -v n="2" '$0~p{i++}i==n' file @WanderingMindawk -v p="two" -v n="2" '$0~p{i++}i==n' file @WanderingMind - Kent
1
@ManuelJordan /two/{A} i==2 {B} = if($0~/two) do A; if(i==2) do B =>@ManuelJordan /two/{A} i==2 {B} = 如果($0匹配/two)执行A;如果i等于2,执行B - Kent
显示剩余7条评论

9

grep和sed可用于过滤行号。

testfile

onefish
onechicken
twofish
twochicken
threechicken
twocows

获取所需行:

grep "two" testfile | sed -n 2p
prints "twochicken"

grep "two" testfile | sed -n 1p
prints "twofish"

5
为了使用grep命令查找第n个匹配项,我们可以使用headtail命令的组合方式,像这样:
grep two file.txt | head -n1 | tail -1

这里的n1是我们需要的第n个匹配项。


1
需要注意的是,如果交换threechickentwocows这两行,也就是:
onefish
onechicken
twofish
twochicken
threechicken
twocows

那么肯特的第一个回应 (awk '/two/{i++}i==2' file) 将产生以下输出:

twochicken
threechicken

由于需要另一次匹配才能增加计数器,因此这会导致问题。他的最后回应:awk '/two/{i++}i==2{print; exit}' file 避免了这个问题。


1

如果一行文字中重复出现了某个单词(此处指word==two),且您希望打印该行文字,请使用以下代码:

word=two
n=2
line=`grep -m$n $word -o -n MyFile | sed -n $n's/:.*//p'`
awk 'FNR=='$line'{print; exit}' MyFile 

e.g. For below input:

onefish
onechicken
twotwofish
twochicken
twocows
threechicken

它将打印twotwofish,而不是twochicken

这可能不是用户1787038想要的,但是我添加了回答我的评论。


在 grep 行中的 -m$n 只是为了一些优化而已,对功能来说并不必需。 - anishsane

0

这个问题与grep有关,所以让我们继续使用它:

$ cat testfile
onefish
onechicken
twofish
twochicken
twocows
threechicken

$ grep two testfile | while read line; do
    ((n++))
    ((n==2)) && { echo "$line"; break; }
done
twochicken

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接