I wrote the following script for finding the number of pdf and tex files from the current directory, including the subdirectories and hidden files. The following code is able to find the number of pdf files upto 2 levels of subdirectories below, but after that it tells that there are no sub directories....


touch t.txt

k=`find -type d |wc -l`
k1=`expr $k - 1`

echo $k1

message1="*.pdf *.tex"
count=`ls -al $message1|wc -l`
find -type d > t.txt


while [ $i -le $k ]
    kd=`head -$i t.txt|tail -1`
    echo $kd
    touch $kd/t.txt
    cp t.txt $kd/t.txt
    i=`expr $i + 1`

while [ $i -le $k ]
    nd=`head -$i t.txt|tail -1`
    set -x
    echo $nd
    set +x
    cd $nd
    j=`ls -al $message1|wc -l`
    count=`expr $count + $j`
    i=`expr $i + 1`
#set +x

echo $count

The answer given by kev will break on files with newlines in the name. You can do this in pure bash:

shopt -s nullglob dotglob globstar
set -- **/*.pdf **/*.tex
echo "$#"
  • Is it relevant to compare the speed of a recursive traversal of a directory branch and a lookup in the current directory? – manatwork Dec 22 '11 at 9:14
  • @manatwork Didn't realise it was also subdirs, fixing now. – Chris Down Dec 22 '11 at 9:17
  • Ok, just one more word: wow! – manatwork Dec 22 '11 at 9:25
  • @ChrisDown: Could you explain this set and $#? – pbm Mar 23 '12 at 15:46
  • @pbm - What do you not understand? set is fairly robustly explained in help set and $# contains the number of arguments. – Chris Down Mar 23 '12 at 19:22

find works fine to me:

$ find . -name '*.pdf' -o -name '*.tex' | wc -l
$ find . -name '*.pdf' | wc -l
$ find . -name '*.tex' | wc -l
$ echo $((16+59))

To handle special case: newline in filename

$ find . \( -name '*.pdf' -o -name '*.tex' \) -printf x | wc -c
  • This will break for files with newlines in their filename. – Chris Down Dec 22 '11 at 8:36
  • It does break, as you can quite clearly see executing the following code: > $'foo\nbar.pdf' ; > $'baz\nqux.tex' ; find . -name '*.pdf' -o -name '*.tex' | wc -l -- the reply is 4, which is not correct (there are two files). – Chris Down Dec 22 '11 at 8:47
  • @ChrisDown. You are right. – kev Dec 22 '11 at 8:54
  • 1
    @ChrisDown: I am always reluctant to make the code more complex only to take into account "newlines in filenames", because I have never seen such a case in everyday situations. Obviously, for code to release to the public, it is correct to take into account every possibility. Are you aware of cases where "newlines in filenames" are not create by mistake or deliberately to test a software? – enzotib Dec 22 '11 at 9:15
  • @enzotib I've seen it multiple times, but only by people using graphical file managers. Often it happens when they go to paste something from another source that contains newlines into a filename, and they don't expect the newlines to still be present. – Chris Down Dec 22 '11 at 9:16

I would recommend (if available) using locate instead of find. You would be querying a database and results would be instant and there is practically no load on the system. Though the database only gets updated when your system runs updatedb so if you wanted up to the second information you would have to make sure that you ran it first and it would put a load on the system but, it depends on how you intend to use your search.

You could use whatever regex meets your needs.

system1:/unix.stackexchange # locate *.tex *.pdf | grep unix.stack.*

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.