Shell-Script zum Fotos komprimieren verbessern

  • Hallo!


    Ich könnte Hilfe beim Verbessern eines Shell-Scriptes brauchen!


    Auf dem Firmenserver liegen massenhaft JPGs in Auflösungen wie sie aktuelle Digitalkameras liefern. 99% der Fotos werden aber nur auf dem Bildschirm wiedergegeben. Also möchte ich diese JPGs besser komprimieren. Ich möchte es unter Linux machen, um mit "touch" der neu komprimierten Datei den Zeitstempel der Originaldatei zu verpassen.


    Also habe ich mir zwei Scripte geschrieben:


    Das erste Script finder.sh sucht mir die Dateien, der dann das zweite Script zum komprimieren und umbenennen aufruft.


    finder.sh
    #!/bin/bash
    find . -name '*.jpg' -exec ./converter.sh {} ';'
    find . -name '*.JPG' -exec ./converter.sh {} ';'


    converter.sh
    #!/bin/bash
    FILE=$1
    DEST=$1.compress


    FILESIZE=$(stat -c %s $FILE)
    echo Source: $FILE ' ' $FILESIZE
    convert -quality 70 $FILE $DEST
    DESTSIZE=$(stat -c %s $DEST)
    DESTSIZEPLUS=$(expr $DESTSIZE + 100000)
    echo Destin: $DEST $DESTSIZE


    if test $DESTSIZEPLUS -le $FILESIZE ; then
    echo "Uebernehme komprimierte Datei! "
    touch $DEST -r $FILE
    rm $FILE
    mv $DEST $FILE
    else
    echo "Lasse bestehende Datei!"
    rm $DEST
    fi


    Ablauf: Finder sucht nach JPGs/jpgs in allen Unterverzeichnissen und ruft je Datei converter.sh auf. Dieser komprimiert mit "convert" die JPGs mit der Qualitätstufe 70 (damit werden die meisten Dateien auf 1/4 bis 1/3 kleiner, die Bildauflösung will ich nicht ändern, da evtl. jemand die Dateien irgendwo in ein Dokument verknüpft hat), dann wird die Größe der beiden Dateien verglichen, und wenn die neu erzeugte Datei mindestens 100kb kleiner ist als die alte wird der Zeitstempel mit "touch" gesetzt, die Datei umbenannt und die Originaldatei gelöscht.


    Was ich noch gerne hätte:
    - Kann man diese zwei Scripte in ein Script umbauen?
    - kann "find" JPG und jpg in einem aufruf finden.
    und am aller wichtigsten.
    - kann ich die if-Bedingung mit "and" erweitern, damit ich prüfen kann ob die neu erstellte Datei auch eine bestimmte Mindestgröße hat, nicht das aus irgendeinem Grund das komprimieren nicht geklappt hat und ich dann die Originaldatei lösche? (wobei natürlich alle gesichert sind!)


    Danke schonmal für die Hilfe.
    Bernhard

  • Zitat

    Original von bma
    - Kann man diese zwei Scripte in ein Script umbauen?


    Bash
    #!/bin/bash
    function converter() {
      FILE=$1 
      ...
    }
    
    
    find . -name '*.jpg' -exec converter {} ';'
    find . -name '*.JPG' -exec converter {} ';'


    Oder so ähnlich.


    Zitat

    Original von bma
    kann "find" JPG und jpg in einem aufruf finden.


    find
    [...]
    -iname pattern
    Like -name, but the match is case insensitive. For example, the


    Evtl. mal damit spielen.


    Christian

  • Hallo!
    Danke für die Antwort.


    "-iname" funktioniert wundebar.


    Aber das mit der "function" funktioniert bei mir nicht. Ich schätze das liegt daran, das find mit exec ein externes Programm aufrufen will und keine function ? Oder ?


    Danke
    Bernhard

  • Zitat

    Original von bma
    Aber das mit der "function" funktioniert bei mir nicht. Ich schätze das liegt daran, das find mit exec ein externes Programm aufrufen will und keine function ? Oder ?


    Leider wohl richtig.


    Probier mal:

    Code
    find . -iname '*.jpg' | while read i ; do converter "$i" ; done


    Christian

  • Und Verknüpfung zweier IFs:

    Code
    if [ 1 == 1  -a  2 == 2 ]; then


    Oder Verknüpfung:

    Code
    if [ 1 == 1  -o  2 == 2 ]; then


    cu
    Markus

  • Danke wilderigel, mahlzeit und hopsi! Mein Script ist jetzt fertig.


    Das mit dem -a beim if bekomme ich trotzdem nicht hin. Verschachtelte ifs habe ich natürlich schon probiert, aber dabei wohl etwas falsch gemacht.


    Gruß
    Bernhard


    PS: Falls es jemanden interessiert, hier ist das fertige Script:


    #!/bin/bash
    function converter(){
    FILE=$1
    DEST=$1.compress


    FILESIZE=$(stat -c %s $FILE)
    echo Source: $FILE ' ' $FILESIZE
    convert -quality 70 $FILE $DEST
    DESTSIZE=$(stat -c %s $DEST)
    DESTSIZEPLUS=$(expr $DESTSIZE + 100000)
    echo Destin: $DEST $DESTSIZE


    if test 100000 -le $DESTSIZE ; then
    if test $DESTSIZEPLUS -le $FILESIZE ; then
    echo "Uebernehme komprimierte Datei! "
    touch $DEST -r $FILE
    rm $FILE
    mv $DEST $FILE
    else
    echo "Lasse bestehende Datei!"
    rm $DEST
    fi
    else
    echo "Lasse bestehende Datei! Datei kleiner 100kb"
    rm $DEST
    fi
    }


    find . -iname '*.jpg' | while read i ; do converter "$i" ; done

  • Zitat

    Original von bma
    Danke wilderigel, mahlzeit und hopsi! Mein Script ist jetzt fertig.


    Das mit dem -a beim if bekomme ich trotzdem nicht hin. Verschachtelte ifs habe ich natürlich schon probiert, aber dabei wohl etwas falsch gemacht.


    Die eckigen Klammern hast Du berücksichtigt? Dann klappt das nämlich auch mit dem "-a"... Nachdem ich bei mir stat und convert nicht installiert hatte, habe ich mal für die beiden eine Prüfung eingebaut. Desweiteren kannst Du dem Skript jetzt auch nen Pfad übergeben, in welchem gesucht wird. Wird nix übergeben, wird das aktuelle Verzeichnis als Suchbasis verwendet. Hoffe das ist OK so ;)


    cu
    Markus


  • Super Mahlzeit! So ist das Script vorzeigbar! Danke für deine Mühe!


    Jetzt hab ich noch eine Addierung der umgewandelten Dateien und der eingesparten MB ergänzt. Der Admin will auch noch ein Logfile, das bekomme ich auch noch hin.


    Außerdem brauche ich noch eine Abfrage VOR dem "convert". In unserem "Archiv" gibt es tatsächlich JPGs mit bis zu 25MB! Das sind dann keine Fotos sondern vom CAD exportiert. "Convert" lastet bei solchen Dateien meinen PC mit 2GB Hauptspeicher ziemlich aus, bei manchen Dateien bricht convert sogar ohne Fehlermeldung ab und die erzeugte Datei hat nur einen Teil des Inhaltes:



    top - 21:44:26 up 1:35, 4 users, load average: 7.49, 3.92, 2.13
    Tasks: 167 total, 1 running, 166 sleeping, 0 stopped, 0 zombie
    Cpu(s): 8.9%us, 3.3%sy, 0.2%ni, 46.2%id, 40.0%wa, 0.0%hi, 1.4%si, 0.0%st
    Mem: 2072860k total, 2020072k used, 52788k free, 1484k buffers
    Swap: 3148700k total, 1302344k used, 1846356k free, 1684540k cached


    PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
    12603 bma 20 0 2535m 1.5g 1.5g D 15 78.0 0:31.04 convert


    Also will ich nurnoch Dateien unten 10MB in den "convert" schicken. Das bekomme ich auch hin.


    Werde morgen abend evtl. erstmal einen Trockenlauf starten. Im "Archiv" sind knapp 103000 JPGs aus den letzten Jahren, bestimmt viele kleine Dateien aus alten Digicams.


    Danke nochmal für die Hilfe!
    Gruß
    Bernhard

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!