Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

What is the Linux command to display how many file names in the directory end in two digits? Using ls with a command like this :

ls -l | wc –l  *[0-9][0-9]
share|improve this question
    
This is one of those times where you should probably be using find, not ls. –  HalosGhost Jun 5 at 16:59
    
You might try: set -- ./*[0-9][0-9] ; echo $# With that you have a +/- accuracy of 2, I think. You can [ -e test ] positionals for -existence to make sure they're really files and not just globs to be sure. –  mikeserv Jun 5 at 17:02
    
what's the reason ls -l *[0-9][0-9] | wc -l wouldn't work? –  Fabricator Jun 5 at 17:37
1  
@user3678068 A directory named foo00 containing a bunch of files with no digits in them would be counted. You need at lead -d. –  derobert Jun 5 at 17:39
    
@derobert, I see. Thanks! –  Fabricator Jun 5 at 17:44

4 Answers 4

In Bash, the following works non-recursively. You can of course put it in a function:

shopt -q nullglob || restore=1 && shopt -s nullglob
var=(*[0-9][0-9])
echo ${#var[@]}
[ 1 -eq "$restore" ] && shopt -u nullglob

That works even if you have crazy file names. If your file names are not crazy, then you can use that ls approach:

ls -d1b *[0-9][0-9] | wc -l

Note that the flags I used to ls are different: -d will make list the directory, not its contents (if you had a directory named something00 for example); -1 says to use a single column for output; -b escapes file names, which will make most crazy file names work.

Both of those will include the directory named something00 in the count. If you need just files, or recursion, find is what you're looking for. This will search the current directory (.), recursively, for files (-type f) only:

find . -type f -name '*[0-9][0-9]' -printf 'f\n' | wc -l

Note the use of -printf, to print just the letter f instead of the file name. You only want to count them, this way its immune to crazy file names.

share|improve this answer

Without wc -l if you want you can use the tree command as below.

tree -P "*[0-9][0-9]" foldername/

Testing

Inside one of my folders, I created 3 files that ends with double digits.

First, I issue ls to see all the files.

bash-3.2$ ls
1aga21  abcd  kshexp.ksh  new.txt  temp  temp1  temp12  temp2  temp3  temp34

Now, I go one folder up to use the tree command.

After that, I issue the tree command as below.

bash-3.2$ tree -P "*[0-9][0-9]" jun4th/
jun4th/
|-- 1aga21
|-- temp12
`-- temp34

0 directories, 3 files

As you can see the final line lists the total files that matches our criteria. The -P flag of tree command is to specify the patterns.

EDIT

As derobert pointed out, if there are directories which ends with 2 numbers and which in turn contains multiple files that ends with 2 numbers the tree command would produce all the files and result in a more noisy output. We can prevent this by tweaking our original command to something like below.

tree -P "*[0-9][0-9]" -L 1 jun4th/

Notice the flag -L 1 which means to look for files only in one sublevel below the current directory.

share|improve this answer

If you don't mind Perl:

perl -E '@a=<*[0-9][0-9]>;say scalar @a'

Note that this (as all other solutions presented so far), assumes that you want to count files whose names end in two or more digits. The file foo123 will be counted as well.

If that's not what you want, the following Perl will print a count of all files (as opposed to files and directories) whose name ends in exactly two digits:

perl -E 'say scalar grep { -f && /[^0-9][0-9]{2}\z/ } <*>'
share|improve this answer
    
good point about the two digits thing. fixed mine. thank you. –  mikeserv Jun 6 at 16:10

Here is a portable way to do the find thing:

find ././ ! -type d -name '*[0-9][0-9]' | grep -c '^\./\./'

And the shell function:

set -- ./*[0-9][0-9]
for f do
    [ -e "$f" ] && echo
done | wc -l

To recursively and portably count files with ls and match only 2-digits exactly at the end of a filename do:

ls ./ -aR1iqp |
grep -c '^ *[0-9].*[^0-9][0-9][0-9]$' 

To search only the current directory do this instead:

ls ./.* ./* -ad1iqp |
grep -c '^ *[0-9].*[^0-9][0-9][0-9]$'
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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