I'm looking for a UNIX command or set of commands, by which I can find the 20 largest files in a directory, based on a specific date range.

To do this I thought I could set the date range by touching a couple of files and then doing a find based on those file dates. i.e.

touch /tmp/point.start -d "2018-06-01 00:00"
touch /tmp/point.end -d "2018-06-30 00:00"

and then run

find . -newer /tmp/point.start ! -newer /tmp/point.end

And to get the lagest 20 files I intended to run, from the directory,

ls -ltr | sort -nk5 | tail -20

But what I can't seem to do is combine the two

find . -newer /tmp/point.start ! -newer /tmp/point.end | ls -ltr | sort -nk5 | tail -20

simply ignores the first part and lists the 20 largest files in the directory regardless of size. I'm sure it's something very obvious I'm missing, but I can't figure out what!

(I'm on RedHat 5.3, and don't have access to newermt)

  • Not having RHEL 5.3 around, does your find have a -printf option? – Jeff Schaller Sep 6 '18 at 13:19
  • you could try to run a -exec instead of piping. – OneK Sep 6 '18 at 13:20
  • 1
    @Jeff, GNU find has had -printf since before Linux let alone RedHat even existed. – Stéphane Chazelas Sep 6 '18 at 13:47

Try this,

find . -newer /tmp/point.start ! -newer /tmp/point.end  ! -path . | xargs ls -ltr | sort -nk5 | tail -20
  • xargs build and execute command lines from standard input
  • worked perfectly. Now my next question is how do I accept this answer? :) – Stuart Douglas Sep 6 '18 at 13:22
  • 1
    no need to pass to xargs just to do an ls -- find ... -ls will do it; just requires you to adjust the sort field – Jeff Schaller Sep 6 '18 at 13:23
  • find . -newer /tmp/point.start ! -newer /tmp/point.end -ls|sort -k7n – Jeff Schaller Sep 6 '18 at 13:24
  • @JeffSchaller Yes, but i too struck like you with RHEL5. – msp9011 Sep 6 '18 at 13:24
  • 1
    @JeffSchaller, it's not only spaces, it's also newlines, quotes, backslashes and some other whitespace characters the list of which depends on the xargs implementations. Some xargs implementations also choke on bytes not forming valid characters. Generally, you can't pipe find to xargs unless you use the -print0/-r0 GNU extensions. But even then it's unnecessary as find supports -exec cmd {} +. – Stéphane Chazelas Sep 6 '18 at 13:40

If you can use -printf with your find:

find . -newer /tmp/point.start ! -newer /tmp/point.end -printf '%s %p\n' | 
  sort -rn | head -20
  • 1
    If you want to find the top 20 file by disk occupation and not by file size, you can use %b %p\n instead of %s %p\n – andcoz Sep 6 '18 at 13:37
  • find . -type f -newer /tmp/point.start ! -newer /tmp/point.end -printf '%s %p\0'|sort -zrn|xargs -0 printf '%s\n'|head -20 would be a slight improvement, though aptly-named files still break head – Jeff Schaller Sep 6 '18 at 13:48

With zsh:

autoload age # best in ~/.zshrc if you use that often
ls -ldS -- *(De:age 2018-06-01 2018-06-30:OL[1,20])
  • -S: sort by size. With GNU ls (as found on RedHat 5.3), you can use -U for not sorting as zsh has sorted the list already with OL.
  • (...): glob qualifier
  • D: don't ignore dot files.
  • e:code: evaluate the code to decide whether to select the file
  • age date1 date2: returns true for files with mtime in that range (without time part, it defaults to 00:00:00)
  • OL: reverse sort by length (size)
  • [1,20]: only select the first 20 ones.

Your Answer

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

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