Can grep show count and matches at the same time? - grep

I've search the web for this but couldn't find the solution I wanted.
I used grep to search for lines having the word one and that works fine.
I want grep to also count the matched lines as well. But I only get the number only.
I tried this but no cigar.
grep -cn 'one' foo
2
Option c is to count and option n is to show lines. But it still shows the count only.
Thus far, this is the only way to do it. Running grep twice :(
grep 'one' foo ; grep 'one' foo | wc -l
one two three
seven one blah
2
Is it possible for grep to show both the matches and the count without repeating the command again?
BTW, I know awk can do this as I've seen in my research. But I want to know if grep can do this. Thanks in advance :)

Related

Grep last match until the end

I've looked around StackExchange sites but I haven't found anything that's quite what I'm looking for. Here are two use cases of grep:
Printing items before/after a match
Print a certain match
I'm trying to parse a log file, and I want to return the last error in the log which is, predictably, at the end of the file. However, sometimes the errors are multiple lines. The answers for 'how to grep the last match' all involve either tail or head, and only work with a single line.
In my case, I want to simply return everything in the file, starting with the last match. Typically, this won't be any more than 10-15 lines maximum, so a grep -A 15 does the trick there. But, I still need to only get the last one of these, so that alone doesn't produce the right output.
The naive approach is to use a two-part match, to first get what the last match is and then everything after that. This won't work for me, because I can't guarantee that the last match is unique.
Is it possible to do this with grep somehow, or would there be better tools for this?
There is a way to get sed to do this but I can't remember.
If you are open to using a combination of commands here is something that might work:
# Get the line number of teh last match
LNO=$( grep -n 'the error' the_file | tail -1 | cut -d":" -f1 )
# Now use sed to print all lines from that point:
sed -n "$LNO,\$p" the_file
I think there's an exact duplicate somewhere, but I found only these close ones:
How to get lines from the last match to the end of file?
grep last match and it's following lines
Here's one way to do it:
$ cat ip.txt
foo123
error 1
xyz
error 2
99999
88888
$ tac ip.txt | sed '/error/q' | tac
error 2
99999
88888

Grep Individual Commands not working when combined in Multi Pattern grep command

I have a need to perform multiple grep matches as part of the same grep command. When I run them individually, they work fine. But not when together. I hope someone could either show me a solution or perhaps can help me find a work-around. Here is sample stream:
(string start..) RollUp:"V" Enzyme:"ENZA ENZB ENZD ENZE" (..string end)
In the first command I am needing to isolate all RollUp substrings.Value is always A or V:
grep -o "RollUp:\"[AV]\""
In the second command I am needing to isolate all combinations of Enzyme values (1-20 total, spaces in between, don't know values names). This command works:
grep -oE 'Enzyme:[[:space:]]*"[^"]+"'
However, I need to match both patterns as part of same stream. When I try:
grep -oE "RollUp:\"[AV]\""\|Enzyme:[[:space:]]*"[^"]+""
, nothing is returned. I would be grateful for any ideas for getting this double grep pattern match to work. Thank you!
regex someting[^"]+ : this means string something followed by anything till next " is seen. Here + sign means , at least one or more match.
grep -oE 'RollUp:"[^"]+|Enzyme:[[:space:]]*"[^"]+"' file

How to filter using grep on a selected word

grep (GNU grep) 2.14
Hello,
I have a log file that I want to filter on a selected word. However, it tends to filter on many for example.
tail -f gateway-* | grep "P_SIP:N_iptB1T1"
This will also find words like this:
"P_SIP:N_iptB1T10"
"P_SIP:N_iptB1T11"
"P_SIP:N_iptB1T12"
etc
However, I don't want to display anything after the 1. grep is picking up 11, 12, 13, etc.
Many thanks for any suggestions,
You can restrict the word to end at 1:
tail -f gateway-* | grep "P_SIP:N_iptB1T1\>"
This will work assuming that you have a matching case which is only "P_SIP:N_iptB1T1".
But if you want to extract from P_SIP:N_iptB1T1x, and display only once, then you need to restrict to show only first match.
grep -o "P_SIP:N_iptB1T1"
-o, --only-matching show only the part of a line matching PATTERN
More info
At least two approaches can be tried:
grep -w pattern matches for full words. Seems to work for this case too, even though the pattern has punctuation.
grep pattern -m 1 to restrict the output to first match. (Also doable with grep xxx | head -1)
If the lines contains the quotes as in your example, just use the -E option in grep and match the closing quote with \". For example:
grep -E "P_SIP:N_iptB1T1\"" file
If these quotes aren't in the text file, and there's blank spaces or endlines after the word, you can match these too:
# The word is followed by one or more blanks
grep -E "P_SIP:N_iptB1T1\s+" file
# Match lines ending with the interesting word
grep -E "P_SIP:N_iptB1T1$" file

Recursively grep results and pipe back

I need to find some matching conditions from a file and recursively find the next conditions in previously matched files , i have something like this
input.txt
123
22
33
The files where you need to find above terms in following files, the challenge is if 123 is found in say 10 files , the 22 should be searched in these 10 files only and so on...
Example of files are like f1,f2,f3,f4.....f1200
so it is like i need to grep -w "123" f* | grep -w "123" | .....
its not possible to list them manually so any easier way?
You can solve this using awk script, i ve encountered a similar problem and this will work fine
awk '{ if(!NR){printf("grep -w %d f*|",$1)} else {printf("grep -w %d f*",$1)} }' input.txt | sh
What it Does?
it reads input.txt line by line
until it is at last record , it prints grep -w %d | (note there is a
pipe here)
which is then sent to shell for execution and results are piped back
to back
and when you reach the end the pipe is avoided
Perhaps taking a meta-programming viewpoint would help. Have grep output a series of grep commands. Or write a little PERL program. Maybe Ruby, if the mood suits.
You can use grep -lw to write the list of file names that matched (note that it will stop after finding the first match).
You capture the list of file names and use that for the next iteration in a loop.

grep for a string which has a specific number in the end

I want to grep for the string THREAD: 2. It has a space in between. Not able to figure out how.
I tried with grep "THREAD:[ \2]", but its not working
Please let me know.
Try grep "THREAD: 2" <filename>? You just want a literal '2', right?
If you are using GNU grep you could try using the alias egrep or grep -e with 'THREAD: 2$'
You might have to use '^.*THREAD: 2$'
grep reports back the entire line that has matched your pattern. If you wish to look at lines that contains THREAD: 2 then the following should work -
grep "THREAD: 2" filename
However, if you wish to fetch lines that could contain THREAD: and any number then you can use a character class. So in that case the answer would be -
grep "THREAD: [0-9]" filename
You can add + after the character class which means one or more numbers so that you can match numbers like 1,2,3 or 11,12,13 etc.
If you only want to fetch THREAD: 2 from your line then you will have to use an option of grep which is -o. It means show me only my pattern from the file not the entire line.
grep -o "THREAD: 2" filename
You can look up man page for grep and play around with all the options.

Resources