Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I am trying to display the filze size in human readable format in following find command

 find $BASE_DIR/ -user $USER -size +$LOWERSIZELIMIT -mtime +$MY_MTIME -type f -printf      "%s %p\n" 2> /dev/null | 
 sort -nr | 

My function to find large files looks like this. It takes in $1 as an argument in order to pass the base directory path to the find command.

 function find_files {
 #echo "In find files"
 # $1 = base directory from where to start the search

 find $1/ -user $USER -size +$LOWERSIZELIMIT -mtime +$MY_MTIME -type f -printf "%s %p\n" 2> /dev/null | sort -nr | head -n $NUMFILES >> $TESTFILE

 if [[ -s $TESTFILE ]] ; 
   echo "***********************************************************************" >> $DUMPFILE
   echo "***********************************************************************" >> $DUMPFILE
   echo "***********************************************************************" >> $DUMPFILE
   echo "***********************************************************************" >> $DUMPFILE
   #cat $TESTFILE
   return 0
   return 1
share|improve this question
First of all, will you please phrase your question in the form of a question? :-) – Scott Feb 18 '13 at 23:18
$BASE_DIR/ and $1/ don’t need the trailing slashes, but they really should be in quotes, as in: find "$1" -user … – Scott Feb 18 '13 at 23:19

Use the -exec option for find (Don't forget to end with \;) If you require only part of the information from your exec command, parse with awk.

find $BASE_DIR/ -user $USER -size +$LOWERSIZELIMIT -mtime +$MY_MTIME -type f -exec /bin/ls -hl {} \;

Use another command if you don't want human readable output of ls, or awk it like so

find $BASE_DIR/ -user $USER -size +$LOWERSIZELIMIT -mtime +$MY_MTIME -type f -exec /bin/ls -hl {} \; | awk '{ print $5,$9 }'

The trickiest parts of find's exec are using {} as the result item for what is found, and the command must end in \; If you have a chain of commands on the same line separated with ; You will need to end your find and then add a ; so there are 2, like some command; find $BASE_DIR/ -user $USER -size +$LOWERSIZELIMIT -mtime +$MY_MTIME -type f -exec /bin/ls -hl {} \;; some command;

share|improve this answer
As for "and the command must end in \;", note that -exec ... + (and xargs ...) is much faster than -exec ... \;. (Test yourself with the time command, or see some other test.) – Arjan Feb 18 '13 at 22:26
Thanks @Arjan. I had not previously used + instead of \; so I read the man page on it. The key difference seems to be that instead of running the command once per match, it runs it once with all matches as arguments. find . -iname ".php" -exec php -l {} + No syntax errors detected in ./1.php find . -iname ".php" -exec php -l {} \; No syntax errors detected in ./1.php No syntax errors detected in ./2.php find . -type f -exec /bin/ls -hl {} + | awk '{ print $5,$9 }' 17 ./1.php 17 ./2.php find . -type f -exec /bin/ls -hl {} \; | awk '{ print $5,$9 }' 17 ./1.php 17 ./2.php – Jon Zobrist Feb 18 '13 at 22:40
I tried the following command but it gave me slightly different result. It gave a list of large files but missed even larger files. find /proj/platform_emulation3/kv/cp/ -user $USER -size +3000k -mtime +3 -exec /bin/ls -hl {} \; | awk '{ print $5,$9 }' | sort -nr | head -n 5 – user199889 Feb 18 '13 at 22:45

The subtlety here is the sort, you cannot (easily & correctly) sort human-readable numbers (unless you have sort from GNU coreutils >= 7.5, it supports a -h option, e.g. du -h | sort -h).

Save the following to hr.awk:

BEGIN { split("KMGTPEZY",suff,//)}
  match($0,/([0-9]+)[ \t](.*)/,bits)
  sz=bits[1]+0; fn=bits[2]
  i=0; while ((sz>1024)&&(i<length(suff))) { sz/=1024;i++ }
  if (i) printf("%.3f %siB %s\n",sz,suff[i],fn)
  else   printf("%3i B %s\n",sz,fn)

Then you can do:

find $BASE_DIR/ -user $USER -size +$LOWERSIZELIMIT -mtime +$MY_MTIME \
  -type f -printf "%s %p\n" 2> /dev/null | sort -nr |
  gawk -f hr.awk | head -n $NUMFILES >> $TESTFILE

The gawk script accepts find ... -printf "%s %p\n" as input, and converts the first field to human-readable size with suffix (in IEC 210 units).

See also this popular question:

share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .