How do I get the find command to print out the file size with the file name?

If I issue the find command as follows:

find . -name *.ear 

It prints out:

./dir1/dir2/earFile1.ear ./dir1/dir2/earFile2.ear ./dir1/dir3/earFile1.ear 

I want to 'print' the name and the size to the command line:

./dir1/dir2/earFile1.ear 5000 KB ./dir1/dir2/earFile2.ear 5400 KB ./dir1/dir3/earFile1.ear 5400 KB 
0

17 Answers

find . -name '*.ear' -exec ls -lh {} \; 

just the h extra from jer.drab.org's reply. saves time converting to MB mentally ;)

6

You need to use -exec or -printf. Printf works like this:

find . -name *.ear -printf "%p %k KB\n" 

-exec is more powerful and lets you execute arbitrary commands - so you could use a version of 'ls' or 'wc' to print out the filename along with other information. 'man find' will show you the available arguments to printf, which can do a lot more than just filesize.

[edit] -printf is not in the official POSIX standard, so check if it is supported on your version. However, most modern systems will use GNU find or a similarly extended version, so there is a good chance it will be implemented.

6

A simple solution is to use the -ls option in find:

find . -name \*.ear -ls 

That gives you each entry in the normal "ls -l" format. Or, to get the specific output you seem to be looking for, this:

find . -name \*.ear -printf "%p\t%k KB\n" 

Which will give you the filename followed by the size in KB.

1

Using GNU find, I think this is what you want. It finds all real files and not directories (-type f), and for each one prints the filename (%p), a tab (\t), the size in kilobytes (%k), the suffix " KB", and then a newline (\n).

find . -type f -printf '%p\t%k KB\n' 

If the printf command doesn't format things the way you want, you can use exec, followed by the command you want to execute on each file. Use {} for the filename, and terminate the command with a semicolon (;). On most shells, all three of those characters should be escaped with a backslash.

Here's a simple solution that finds and prints them out using "ls -lh", which will show you the size in human-readable form (k for kilobytes and M for megabytes):

find . -type f -exec ls -lh \{\} \; 

As yet another alternative, "wc -c" will print the number of characters (bytes) in the file:

find . -type f -exec wc -c \{\} \; 
3
find . -name '*.ear' -exec du -h {} \; 

This gives you the filesize only, instead of all the unnecessary stuff.

2

Awk can fix up the output to give just what the questioner asked for. On my Solaris 10 system, find -ls prints size in KB as the second field, so:

% find . -name '*.ear' -ls | awk '{print $2, $11}' 5400 ./dir1/dir2/earFile2.ear 5400 ./dir1/dir2/earFile3.ear 5400 ./dir1/dir2/earFile1.ear 

Otherwise, use -exec ls -lh and pick out the size field from the output. Again on Solaris 10:

% find . -name '*.ear' -exec ls -lh {} \; | awk '{print $5, $9}' 5.3M ./dir1/dir2/earFile2.ear 5.3M ./dir1/dir2/earFile3.ear 5.3M ./dir1/dir2/earFile1.ear 

Why not use du -a ? E.g.

find . -name "*.ear" -exec du -a {} \; 

Works on a Mac

1

Try the following commands:

GNU stat:

find . -type f -name *.ear -exec stat -c "%n %s" {} ';' 

BSD stat:

find . -type f -name *.ear -exec stat -f "%N %z" {} ';' 

however stat isn't standard, so du or wc could be a better approach:

find . -type f -name *.ear -exec sh -c 'echo "{} $(wc -c < {})"' ';' 

I struggled with this on Mac OS X where the find command doesn't support -printf.

A solution that I found, that admittedly relies on the 'group' for all files being 'staff' was...

ls -l -R | sed 's/\(.*\)staff *\([0-9]*\)..............\(.*\)/\2 \3/' 

This splits the ls long output into three tokens

  1. the stuff before the text 'staff'
  2. the file size
  3. the file name

And then outputs tokens 2 and 3, i.e. output is number of bytes and then filename

8071 sections.php 54681 services.php 37961 style.css 13260 thumb.php 70951 workshops.php 
1

This should get you what you're looking for, formatting included (i.e. file name first and size afterward):

find . -type f -iname "*.ear" -exec du -ah {} \; | awk '{print $2"\t", $1}' 

sample output (where I used -iname "*.php" to get some result):

./plugins/bat/class.bat.inc.php 20K ./plugins/quotas/class.quotas.inc.php 8.0K ./plugins/dmraid/class.dmraid.inc.php 8.0K ./plugins/updatenotifier/class.updatenotifier.inc.php 4.0K ./index.php 4.0K ./config.php 12K ./includes/mb/class.hwsensors.inc.php 8.0K 

Just list the files (-type f) that match the pattern (-name '*.ear) using the disk-usage command (du -h) and sort the files by the human-readable file size (sort -h):

find . -type f -name '*.ear' -exec du -h {} \; | sort -h 

Output

5.0k ./dir1/dir2/earFile1.ear 5.4k ./dir1/dir2/earFile2.ear 5.4k ./dir1/dir3/earFile1.ear 

You could try this:

find. -name *.ear -exec du {} \; 

This will give you the size in bytes. But the du command also accepts the parameters -k for KB and -m for MB. It will give you an output like

5000 ./dir1/dir2/earFile1.ear 5400 ./dir1/dir2/earFile2.ear 5400 ./dir1/dir3/earFile1.ear 
find . -name "*.ear" | xargs ls -sh 
 $ find . -name "test*" -exec du -sh {} \; 4.0K ./test1 0 ./test2 0 ./test3 0 ./test4 $ 

Scripter World reference

0
find . -name "*.ear" -exec ls -l {} \; 

If you need to get total size, here is a script proposal

#!/bin/bash totalSize=0 allSizes=`find . -type f -name *.ear -exec stat -c "%s" {} \;` for fileSize in $allSizes; do totalSize=`echo "$(($totalSize+$fileSize))"` done echo "Total size is $totalSize bytes" 

You could try for loop:

for i in `find . -iname "*.ear"`; do ls -lh $i; done 

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

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

You Might Also Like