SoftTimur
SoftTimur

Reputation: 5510

Search for exact match of a line

I would like to find in a set of files the exact mach of a line hello world. For instance, let's say test1.txt and test2.txt are all the .txt in the folder, and test1.txt is:

hello world
a hello world

and test2.txt is:

hello world b
helloworld
hello world
hello world

I would expect 3 as return for hello world. But what I know is grep -l "hello world" *.txt | wc -l, which doesn't work well.

Could anyone help?

Upvotes: 0

Views: 987

Answers (5)

X Zhang
X Zhang

Reputation: 307

find . -name "you want file patterns" | xargs grep -x "hello world" | wc -l

In your situation, the desired command is:

find . -name "*.txt" | xargs grep -x "hello world" | wc -l

Upvotes: 0

Digital Trauma
Digital Trauma

Reputation: 15996

grep is generally the best and fastest tool for this, but for the record, if you want a pure bash method, you could do:

$ { c=0; while IFS='' read -r line; do [ "$line" = "hello world" ] && ((c++)); done; echo $c; } < test.txt 
2
$ 

A comment asks "Why unset IFS?". Consider what happens if we have whitespace at the beginning or end of a line (I assume from the question, we want an exact match, so the extra whitespace should cause the match to fail):

$ echo " hello world" | { c=0; while read -r line; do [ "$line" = "hello world" ] && ((c++)); done; echo $c; }
1
$ echo " hello world" | { c=0; while IFS='' read -r line; do [ "$line" = "hello world" ] && ((c++)); done; echo $c; }
0
$ 

If IFS is set, then read will split the line according to IFS and then assign the resulting tokens to variables. Since we have whitespace at the beginning, then this is treated as a separator and is effectively discarded.


In fact if we use the builtin variable $REPLY, we don't need to worry about IFS at all. So:

{ c=0; while read -r; do [ "$REPLY" = "hello world" ] && ((c++)); done; echo $c; } < test.txt

Upvotes: 0

Bruce
Bruce

Reputation: 1

grep has the special characters '^' to match the beginning of the line, and '$' to match the end, so if you do:

grep "^hello world$" *.txt

You will get the lines you are looking for, and you can add a "| wc -l" for the count, or concatenate the lines and use the -c option to grep (as someone above suggested).

Upvotes: 0

user2719058
user2719058

Reputation: 2233

grep -Fcx 'hello world'

should do it. For multiple input files, use

cat *.txt | grep -Fcx 'hello world'

This way, the cat combines the files into one input stream for grep, providing a global count.

Upvotes: 2

Ryan Loggerythm
Ryan Loggerythm

Reputation: 3314

grep -x -c "hello world" test.txt

that will give you 2 as a result.

and if you want to know what lines your hits can be found on, you can use

grep -n -x "hello world" test.txt

Upvotes: 0

Related Questions