Question

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

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

./dir1/dir2/earFile1.ear  5000 KB
./dir1/dir2/earFile2.ear  5400 KB
./dir1/dir3/earFile1.ear  5400 KB
Was it helpful?

Solution

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

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

OTHER TIPS

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.

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.

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, 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 \{\} \;
find . -name '*.ear' -exec du -h {} \;

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

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

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

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

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

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 < {})"' ';'
find . -name "*.ear" -exec ls -l {} \;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top