Chris
Chris

Reputation: 3

Bash scripting - output lines with matching pattern AND the count

I'm trying to find the number of lines in a file that match a certain pattern and find the number of lines that matched. For example, if my file were

test1 type1 random1

test2 type2 bird

dog cat random

I want to find the lines that have "random" and the number of lines. Ideally, the output would be something like

test1 type1 random1

dog cat random

2

I know how to use grep to do either of these tasks individually, but if I'm working with a large file, I'd prefer to not read the file twice. I'd also like to stay away from making an additional temp file to store the results of grep.

Is there a command and/or a simple function I can write to achieve these results?

Upvotes: 0

Views: 492

Answers (5)

anishsane
anishsane

Reputation: 20980

awk variant for this problem statement is more optimized. But if you don't want to use awk, here is grep+wc variant:

In case, you want to use grep, instead of awk.

$ grep -F random random.log | tee /dev/tty | wc -l
test1 type1 random1
dog cat random
2

Upvotes: 1

tripleee
tripleee

Reputation: 189937

I like the awk solutions here, but as always, there's more than one way to skin a cat. If you number the output lines with nl it's easy to see how many matches you got.

grep stuff from files | nl

Getting exactly the output you specified in the question is a simple matter of postprocessing (though I would not bother). Pipe to a simple sed script to remove the line number, then print the latest removed number at the end.

grep stuff from files |
nl |
sed -n 'h                    # Keep a copy in hold space
     s/^ *[1-9][0-9]*\t//p   # Print without number
     $!b                     # Unless at last line, we're done
     x                       # Retrieve from hold space
     s/\t.*//p'              # Print only line number

(If your sed dialect does not recognize \t as a literal tab, or cannot cope with comments on the same line, you'll need to adapt this. In most shells, you can type a literal tab with ctrl-V tab.)

Upvotes: 1

Mahesh Kharvi
Mahesh Kharvi

Reputation: 399

awk '/random/{count++;print}END{print count}' file

If match found, increment the counter and print. Print the count at the end.

Upvotes: 2

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

Reputation: 799560

Nope.

$ cat t.txt
foo: bar
foo: quux
bar: baz
$ awk -v regex='bar' '$0 ~ regex { count++; print } END {print count}' t.txt
foo: bar
bar: baz
2

Upvotes: 2

luoluo
luoluo

Reputation: 5533

awk 'BEGIN{total=0} {if(/random/) {total+=1; print $0;}}END{print total}' input_file

Upvotes: 2

Related Questions