Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Why do that when a loop is clearer, safer, and shorter?

  find images -name '*.jpg' | while read jpg; do
      convert -geometry 200x "$jpg" "$(echo "$jpg" | sed 's/.jpg$/_thumb.jpg/')";
  done
This version works even when there are spaces in a filename, whereas yours will break.


false

    $ ls -Ql
    totale 4
    -rw-r--r-- 1 zed users 33 set  6 07:30 "    spaces    "
    $
    $ find -name '*spaces*' | while read text; do
        cat "$text";
    done
    cat: ./    spaces: File o directory non esistente
    $
    $ find -name '*spaces*' -print0 | xargs -0 cat
    while read is broken with spaces
    $


IFS needs some care and attention and read should have -r.

    $ ls -Q
    "   spaces   "
    $ ls | while IFS="\n" read -r f; do ls "$f"; done
       spaces   
    $
For lots of grim detail see David A. Wheeler's http://www.dwheeler.com/essays/fixing-unix-linux-filenames.h...


That is a good point, but it is a much more degenerate case than the more common internal space.


Only for file names starting or ending with spaces, as far as I can tell, which are pretty unusual.


You can parallelize this operation with xargs simply by adding a -P. You could add a & to your convert here but that would run all the jobs at the same time. xargs allows you to only run n at a time. That would be a lot harder to replicate in bash.


Why use sed here?

    find images -name "*.jpg" | while read -r jpg; do
        convert -geometry 200x "$jpg" "${jpg%.jpg}_thumb.jpg"
    done
This correctly handles spaces in file names and uses built in shell string replacement.


Even shorter, avoiding the echo sed business:

  find images -name '*.jpg' | while read jpg; do
      convert -geometry 200x "$jpg" "${jpg%%.jpg}_thumb.jpg";
  done




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: