1

I wrote the following command to list all files in and below '~' by order of file size. It seems to work fine:

find ~ -printf "%k KB %p\n" | sort -nr

Now I want to put this is a shell script and loop through the results to do more processing.

I got this to work with a simple 'ls' command:

dir="/home/myusername"
cmd='ls'
for i in `$cmd`
do
  echo $i
done

But this doesn't work:

dir="/home/myusername"
cmd='find $dir -printf "%k KB %p\n" | sort -nr'
for i in `$cmd`
do
  echo $i
done

I've also tried using escape characters in front of the double-quotes, but that didn't work either ...

dir="/home/myusername"
cmd='find $dir -printf \"%k KB %p\n\" | sort -nr'
for i in `$cmd`
do
  echo $i
done

Any ideas what I'm doing wrong?

  • @BroSlow hi -- thanks for the help, but that was a typo in my question -- I changed the "~" to "$dir" -- thx –  Jan 27 '14 at 00:38
  • No problem, also see http://stackoverflow.com/a/11366230/3076724 to fix your `find` syntax, otherwise it will break on spaces/weird characters. – Reinstate Monica Please Jan 27 '14 at 00:38
  • possible duplicate of [find while loop with files containing spaces in bash](http://stackoverflow.com/questions/11366184/find-while-loop-with-files-containing-spaces-in-bash) – that other guy Jan 27 '14 at 00:41
  • @thatotherguy thanks, but I don't think it's the same issue. I'm just trying to run the admitted tricky command and the escape characters aren't working –  Jan 27 '14 at 00:53
  • @RobertHume The escape characters aren't working because your approach is fundamentally flawed. To loop over results, use the linked question's method (and `sort -z` to sort). – that other guy Jan 27 '14 at 01:00
  • Part of the problem is that you're trying to put the command in a variable before executing it, and that'll fail when the command contains anything nontrivial (in this case, quotes and a pipe). See [BashFAQ #50: I'm trying to put a command in a variable, but the complex cases always fail!](http://mywiki.wooledge.org/BashFAQ/050). – Gordon Davisson Jan 27 '14 at 02:35

3 Answers3

3

Try this while loop with find in BASH:

while read -r f; do
    echo "$f"
done < <(find "$dir" -printf "%k KB %p\n" | sort -nr)
anubhava
  • 761,203
  • 64
  • 569
  • 643
2

To execute simple commands, you can pipe the results of find into xargs:

find ~ -printf "%k KB %p\n" | sort -nr | xargs -l -i echo '{}'

-l: makes xargs process one line at a time.

-i: substitutes each occurrence of {} with the output of the pipe.

Gerrit Brouwer
  • 732
  • 1
  • 6
  • 14
0

This should work (see https://stackoverflow.com/a/11366230/3076724 for an explanation of why not to use original syntax)

find "$dir" -printf "%k KB %p\n" | sort -nr |  while read -r i; do
  echo "$i"
done
Community
  • 1
  • 1
Reinstate Monica Please
  • 11,123
  • 3
  • 27
  • 48