Display only the n'th match of grep
Solution 1
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
Solution 2
grep -m2 "two" in-file.txt | tail -n1
Stop after the second match, then take the second line printed.
Solution 3
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"
Solution 4
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.
Solution 5
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.
Andrew Tsay
Updated on July 09, 2022Comments
-
Andrew Tsay almost 2 years
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".
-
poncha about 11 yearsthe second option is superior regardless of filesize, no ?
-
poncha about 11 yearsthat does not exactly do what is expected. if there are more matches than two, it will output multiple lines...
-
poncha about 11 yearswhat do you mean by 'line number' ? i meant that adding
{print; exit}
would be good idea for any input size... oh. that was option #3 actually ;) i counted wrong))) -
Thor about 11 yearsThe tail should be:
tail -n1
. -
John Zwinck about 11 years@poncha: really? The grep -m2 makes sure there are only two matches. I changed it anyway, though I think it was OK before.
-
anishsane about 11 yearsis there a way to stop at nth occurrence of the word? I mean, if the "word" is repeated multiple times in a single line?
-
anishsane about 11 years
-m$n
in grep line is just for some optimization, not needed for functionality. -
Kent about 11 years@anishsane i think there is.
-
rambalachandran almost 8 yearsIs there a way to pass a the
search-pattern
and the no. of occurenceN
as a string -
Kent almost 8 years@WanderingMind yes, you can define variables
-
rambalachandran almost 8 yearsCan you edit your answer to let me know how to pass a variable as search pattern
-
Kent almost 8 years
awk -v p="two" -v n="2" '$0~p{i++}i==n' file
@WanderingMind -
rambalachandran almost 8 yearsThank you for the reply.
-
DreadPirateShawn over 6 yearsThis is buggy -- if you remove
twocows
from the example, then it prints bothtwocows
andthreechickens
, becausei
only iterates on lines that include "two" -- so ifi
reaches 2 on the last occurrence of the target string, theni
remains 2 throughout the rest of the file, and every subsequent line is printed. (However, the "if your file is huge" addendum fixes this bug.) -
Manuel Jordan over 2 years@Kent can you please explain what does
{i++}i==2
do? -
Kent over 2 years@ManuelJordan
/two/{A} i==2 {B}
=if($0~/two) do A; if(i==2) do B