I have 40 files in a directory and I want to count the number of times there is a line with a "2" in the first column in each file individually.

I am trying something like this, but it prints out the total sum from each file and I want the individual sums:

find . -type f -print0 | xargs -0 awk '($1=="2"){++count} END {print count}'

Just to make it clear this is an example:


2   345     123     4
2   4567    2344    6
3   2345    657     87
6   234     345     6


1   12  436 7
2   54  86  8
2   23  48  0
2   098 0   8
8   98  9   0


FILE_1 2
FILE_2 3

What I'm actually getting:



Thanks for your help!


You can have grep count them for you. Assuming the lines you need start with 2, you can use the following:

grep -c '^[[:space:]]*2\>' $(find . -type f -print0 | xargs -0 echo)

The \> at the end of the regex ensures matching will stop at a "word boundary" to avoid false alarms such as lines starting with 20 instead of 2.


If the "40 files" you're looking for are all in the same directory (not in sub-directories), you can make find search the current directory only without recursing (so that you get less latency) like so:

find -maxdepth 1 . -type f -print0


To match files where the 2 occurs in a different column to the first, you can do this:

grep -cE "^[[:space:]]*([0-9]+[[:space:]]+){$TOMATCH}2\>" \
$(find . -type f -print0 | xargs -0 echo)

You can change COLNUM as needed. Basically, what this does is, it attempts to match COLNUM-1 columns followed by a 2 at a word boundary. The -E switch is needed to enable extended regular expressions which allows you to use the {} notation to specify a numerical quantifier (i.e. 'match the previous pattern this many times').

Note however,that if you enter a column number that doesn't exist in the file the regex will fail silently.

  • Thanks! I was getting more because it was also counting lines that had other values (20 for example) that started with a 2 but I fixed it with grep -wc
    – Rebe
    Jul 10 '13 at 20:22
  • @Rebe Edited answer to make a provision for that in the regex.
    – Joseph R.
    Jul 10 '13 at 20:31
  • @Rebe You should note that this solution doesn't scale well as the find command needs to have listed all the files before the grep begins. If you're looking at a large number of files, the pipe-lined solutions in the other answers are probably more well-suited for you.
    – Joseph R.
    Jul 10 '13 at 20:36
  • Can you use grep to find a value in a different column and not just at the start of the line?
    – Rebe
    Jul 10 '13 at 21:01
  • @Rebe Give me more info: are "columns" made up of digits only? Are we sure that columns are delimited by whitespace only?
    – Joseph R.
    Jul 10 '13 at 21:02

A couple of solutions:

  1. execute awk on each file using find -exec option:

    find . -type f \
    -exec awk '($1=="2"){++count}END{print FILENAME ": " count}' {} \;
  2. use awk FNR variable to detect file change in awk script:

    find . -type f -print0 | xargs -0 \
    awk 'FNR==1{if (NR!=1){print count} printf("%s: ", FILENAME);}($1=="2"){++count}END{print count}'
  • The first one works great. The second one isn't what I'm really looking for but it's good to know ho to do that. Thanks!
    – Rebe
    Jul 10 '13 at 21:15
  • And I like that it uses awk so I can use it for other columns!
    – Rebe
    Jul 10 '13 at 21:16

If you don't mind changing the output you can do the following:

$ grep "^2" *|awk '{print $1}'|uniq -c
      2 FILE_1:2
      3 FILE_2:2

If you want your PRINT output:

$ grep "^2" *|awk '{print $1}'|uniq -c|sed 's/:2//'|awk '{print $2, $1}'
FILE_1 2
FILE_2 3
  • @Rebe - yeah it's less efficient but easier to follow.
    – slm
    Jul 10 '13 at 21:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.