Views:
9,868β
Votes: 2β
Tags:
command-line
bash
scripts
files
find
Link:
π See Original Answer on Ask Ubuntu β§ π
URL:
https://askubuntu.com/q/1023474
Title:
How can I count files with a particular extension, and the directories they are in?
ID:
/2018/04/09/How-can-I-count-files-with-a-particular-extension_-and-the-directories-they-are-in_
Created:
April 9, 2018
Edited: June 12, 2020
Upload:
September 15, 2024
Layout: post
TOC:
false
Navigation: false
Copy to clipboard: false
Consider using the locate
command which is much faster than find
command.
Running on test data
$ sudo updatedb # necessary if files in focus were added `cron` daily.
$ printf "Number Files: " && locate -0r "$PWD.*\.c$" | xargs -0 -I{} sh -c 'test ! -L "$1" && echo "regular file"' _ {} | wc -l && printf "Number Dirs.: " && locate -r "$PWD.*\.c$" | sed 's%/[^/]*$%/%' | uniq -cu | wc -l
Number Files: 29
Number Dirs.: 7
Thanks to Muru for his answer to help me through stripping symbolic links out of the file count in Unix & Linux answer.
Thanks to Terdon for his answer of $PWD
(not directed at me) in Unix & Linux answer.
Original answer below referenced by comments
Short Form:
$ cd /
$ sudo updatedb
$ printf "Number Files: " && locate -cr "$PWD.*\.c$"
Number Files: 3523
$ printf "Number Dirs.: " && locate -r "$PWD.*\.c$" | sed 's%/[^/]*$%/%' | uniq -c | wc -l
Number Dirs.: 648
sudo updatedb
Update database used bylocate
command if.c
files were created today or if youβve deleted.c
files today.locate -cr "$PWD.*\.c$"
locate all.c
files in the current directory and itβs children ($PWD
). Instead of printing file names, and print count with-c
argument. Ther
specifies regex instead of default*pattern*
matching which can yield too many results.locate -r "$PWD.*\.c$" | sed 's%/[^/]*$%/%' | uniq -c | wc -l
. Locate all*.c
files in current directory and below. Remove file name withsed
leaving only directory name. Count number of files in each directory usinguniq -c
. Count number of directories withwc -l
.
Start at current directory with one-liner
$ cd /usr/src
$ printf "Number Files: " && locate -cr "$PWD.*\.c$" && printf "Number Dirs.: " && locate -r "$PWD.*\.c$" | sed 's%/[^/]*$%/%' | uniq -c | wc -l
Number Files: 3430
Number Dirs.: 624
Notice how file count and directory count have changed. I believe all users have the /usr/src
directory and can run above commands with different counts depending on number of installed kernels.
Long Form:
The long form includes the time so you can see how much faster locate
is over find
. Even if you have to run sudo updatedb
it is many times faster than a single find /
.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
rick@alien:~/Downloads$ sudo time updatedb
0.58user 1.32system 0:03.94elapsed 48%CPU (0avgtext+0avgdata 7568maxresident)k
48inputs+131920outputs (1major+3562minor)pagefaults 0swaps
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
rick@alien:~/Downloads$ time (printf "Number Files: " && locate -cr $PWD".*\.c$")
Number Files: 3523
real 0m0.775s
user 0m0.766s
sys 0m0.012s
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
rick@alien:~/Downloads$ time (printf "Number Dirs.: " && locate -r $PWD".*\.c$" | sed 's%/[^/]*$%/%' | uniq -c | wc -l)
Number Dirs.: 648
real 0m0.778s
user 0m0.788s
sys 0m0.027s
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Note: This is all files on ALL drives and partitions. ie we can search for Windows commands too:
$ time (printf "Number Files: " && locate *.exe -c)
Number Files: 6541
real 0m0.946s
user 0m0.761s
sys 0m0.060s
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
rick@alien:~/Downloads$ time (printf "Number Dirs.: " && locate *.exe | sed 's%/[^/]*$%/%' | uniq -c | wc -l)
Number Dirs.: 3394
real 0m0.942s
user 0m0.803s
sys 0m0.092s
I have three Windows 10 NTFS partitions automatically mounted in /etc/fstab
. Be aware locate knows everything!
Interesting Count:
$ time (printf "Number Files: " && locate / -c && printf "Number Dirs.: " && locate / | sed 's%/[^/]*$%/%' | uniq -c | wc -l)
Number Files: 1637135
Number Dirs.: 286705
real 0m15.460s
user 0m13.471s
sys 0m2.786s
It takes 15 seconds to count 1,637,135 files in 286,705 directories. YMMV.
For a detailed breakdown on locate
commandβs regex handling (appears not to be needed in this Q&A but used just in case) please read this: Use "locate" under some specific directory?
Additional reading from recent articles: