Reputation: 5510
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
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
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
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
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
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