51
onefish
onechicken
twofish
twochicken
twocows
threechicken

What if I want to grep for lines containing "two", but I only want the 2nd match. So I want the result "twochicken".

Anders R. Bystrup
  • 15,729
  • 10
  • 59
  • 55
Andrew Tsay
  • 1,893
  • 6
  • 23
  • 35

7 Answers7

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

Stop after the second match, then take the second line printed.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • 1
    that does not exactly do what is expected. if there are more matches than two, it will output multiple lines... – poncha Feb 28 '13 at 12:34
  • 3
    The tail should be: `tail -n1`. – Thor Feb 28 '13 at 13:01
  • 1
    @poncha: really? The grep -m2 makes sure there are only two matches. I changed it anyway, though I think it was OK before. – John Zwinck Feb 28 '13 at 14:29
  • This is a really poor answer, because it doesn't work for multi-line matches (i.e. in combination with `-A` or `-B`. HOWEVER, none of the other alternatives works for multi-line matches either. – Chiarcos Nov 08 '22 at 00:45
  • A possible solution for multi-line results is described under https://superuser.com/questions/1086675/using-grep-how-do-i-show-the-nth-occurence-of-a-pattern. – Chiarcos Nov 08 '22 at 00:53
36

try this:

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

with your data:

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

note: if your file is huge, do this:

awk '/two/{i++}i==2{print; exit}' file
Kent
  • 189,393
  • 32
  • 233
  • 301
9

grep and sed can be used to filter the line number.

testfile:

onefish
onechicken
twofish
twochicken
threechicken
twocows

Getting the desired line:

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

grep "two" testfile | sed -n 1p
prints "twofish"
Joy
  • 187
  • 3
  • 7
5

To use grep command for the n_th match, we can use the combination of head and tail commands like this:

grep two file.txt | head -n1 | tail -1

where n1 is the n_th match we need.

Louis
  • 766
  • 7
  • 10
1

If the word (here word==two) repeats multiple time in a single line, & you want to print that line, use below:

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

it will print twotwofish, instead of twochicken.

This may not be what user1787038 wants, but added to answer my own comment.

anishsane
  • 20,270
  • 5
  • 40
  • 73
1

It should be noted that if the threechicken and twocows lines were swapped, aka:

onefish
onechicken
twofish
twochicken
threechicken
twocows

then Kent's first response (awk '/two/{i++}i==2' file) would yield the output:

twochicken
threechicken

because it takes another occurrence of the match to increment the counter. His last response: awk '/two/{i++}i==2{print; exit}' file avoids this issue.

Alex
  • 301
  • 4
  • 4
0

The question is about grep so let's stick with it:

$ cat testfile
onefish
onechicken
twofish
twochicken
twocows
threechicken

$ grep two testfile | while read line; do
    ((n++))
    ((n==2)) && { echo "$line"; break; }
done
twochicken
Ivan
  • 6,188
  • 1
  • 16
  • 23