4

In UNIX I can do the following:

grep -o 'string' myFile.txt | wc -l

which will count the number of lines in myFile.txt containing the string. Or I can use :

grep -o 'string' *.txt | wc -l

which will count the number of lines in all .txt extension files in my folder containing the string. I am looking for a way to do the count for all files in the folder but to see the output separated for each file, something like:

myFile.txt 10000

myFile2.txt 20000

myFile3.txt 30000

I hope I have made my self clear, if not you can see a somewhat close example in the output of :

wc -l *.txt
Community
  • 1
  • 1
Ravid Goldenberg
  • 2,119
  • 4
  • 39
  • 59

2 Answers2

6

Why not simply use grep -c which counts matching lines? According to the GNU grep manual it's even in POSIX, so should work pretty much anywhere.

Incidentally, your use of -o makes your commands count every occurence of the string, not every line with any occurences:

$ cat > testfile
hello hello
goodbye
$ grep -o hello testfile
hello
hello

And you're doing a regular expression search, which may differ from a string search (see the -F flag for string searching).

Yann Vernier
  • 15,414
  • 2
  • 28
  • 26
1

Use a loop over all files, something like

for f in *.txt; do echo -n $f $'\t'; echo grep 'string' "$f" | wc -l; done

But I must admit that @Yann's grep -c is neater :-). The loop can be useful for more complicated things though.

Peter - Reinstate Monica
  • 15,048
  • 4
  • 37
  • 62
  • Use "$f" for files like "Count my lines.txt" and remove the -o as @Yann explained. – Walter A Feb 04 '16 at 09:03
  • @WalterA Oh. I didn't quite understand Yann's comment properly. Thanks! But `"$f"` wouldn't really help because the globbing (is that the term?) produces single words already. (`grep -c string *.txt` fails in the same way.) One should use `find -print0` with `xargs -0`, but I had the feeling that the OP was not familiar with loops (or he wouldn't have asked), so it is not meant as a production quality solution but merely as a concept. – Peter - Reinstate Monica Feb 04 '16 at 09:21
  • @WalterA Hm. I take that back -- `grep -c string *.txt` with one file `a b c.txt` works (cygwin here). How? Shouldnt it just expand to `grep -c string a b c.txt`, and none of these 3 files exist? – Peter - Reinstate Monica Feb 04 '16 at 09:30
  • The expansion is done once. The shell will give the expanded *.txt as one argument. The problem starts when using in a for. After touching "a b c.txt" try `for f in *.txt; do echo $f; grep x $f; done` and `for f in *.txt; do echo $f; grep x "$f"; done`. – Walter A Feb 04 '16 at 09:43
  • @WalterA Thanks, instructive. So the result of Pathname Expansion is a true list of strings, not a single string. I never knew. – Peter - Reinstate Monica Feb 04 '16 at 10:10
  • The expansion is aware that `a b c.txt` is one word, and in a Unixy environment (like Linux or, hopefully, Cygwin) this form can be preserved as programs receive a simple array of arguments (argv). Other operating systems may use different calling conventions, such as DOS which passes a single string, leaving the program to split it into arguments. It's the expansion of `$f` which causes a second splitting into multiple words; avoid it by using `"$f"`. – Yann Vernier Feb 15 '16 at 14:25
  • @YannVernier Thanks for the clarification. I was indeed not aware of that until I read Walter's comment and had this discussion. Yes, of course, cygwin handles arguments the same way :-). – Peter - Reinstate Monica Feb 15 '16 at 15:38