28 May 2009

Zautomatyzowana konwersja plików

Często do automatycznej konwersji plików pisze się pętle, wyglądające mniej więcej tak:

Sposób 1

#!/bin/bash
IFS=$'\n'

for filename in `ls *.png`; do
   # TODO: Execute sth on each file
   #       this is only example (it may not work - not tested)

   new_file_name=`basename $filename .png`
   convert $filename $new_file_name
done
Sposób fajny, ale za każdym razem trzeba to napisać/skopiować. Jest również rozwiązanie prostsze:

Sposób 2

ls *.png | xargs -I{} echo convert "{}" '`basename {} .png`'.eps > runme.sh && \
bash runme.sh && \
rm runme.sh

Podsumowując

Wynik działania obu skryptów powinien być identyczny - niemniej jednak skrypt numer 1 powinine być wykorzystany, jeżeli wymagane jest wykonanie wielu operacji na jednym pliku. Natomiast skrypt numer 2 ma taką zaletę, że można go napisać w jednej linii - nie jest wymagane tworzenie osobnego pliku .sh.

3 comments:

  1. wszystko ok, ale:
    - nieskalowalne - ls wyświetli określoną liczbe parametrów, po czym powie fuck off, argument list too long.
    - skomplikowane. szybciej chyba:

    find -iname *.png -exec convert {}\;


    cnie ? :)

    ReplyDelete
  2. AFAIR:

    Bash się wywala w momencie: ls * jak masz za dużo plików ;) - wynika to z ograniczeń dostępnych ilości parametrów dla każdego programu (correct me if I'm wrong).

    co do:

    find . -iname '*.png' -maxdepth 1 -exec convert "{}" "{}".eps \;

    dostaniesz pliki wynikowe z *.png.eps ;), ale możesz puścić całość poprzez echo do pliku i uruchomić znacznie prościej:

    Kod by wyglądał tak:

    find . -iname '*.png' -maxdepth 1 -exec echo "convert \"{}\" `basename \"{}\" .png`" \; > runme.sh


    taaak, wiem lubię komplikować (nie uruchamiałem tego o wyżej napisałem ale powinno latać).

    ReplyDelete
  3. wsio zalezy :) mi tam generalnie nie przeszkadzaja .png.eps :-D

    ReplyDelete