Bilder aus Verzeichnis konvertieren

W

wilder

GNU/Linux Anfänger
Code:
#!/bin/sh

if [ $1="" ]
then

  echo ""
  echo "  bildklein [dateityp-1] [größe] [verzeichnis] [präfix] [dateityp-2]"
  echo ""
  echo "  dateityp-1  - (z.B. jpg, png, gif, tif) Von alle Datei diese Dateityps im aktuellen Verzeichnis"
  echo "                werden Verkleinerungen angelegt."
  echo "  größe       - (z.B. 640x480) Welche Pixelbreite und -höhe (x/y) sollen die neuen Bilder haben."
  echo "  verzeichnis - Den Namen für das Unterverzeichnis, in dem die neuen Bilder abgespeichert werden"
  echo "                sollen."
  echo "  präfix      - (z.B. klein-) Welches Präfix sollen die verkleinerten Bilder erhalten."
  echo "  dateityp-2  - Welchen Dateityp sollen die neuen verkleinerten Bilder haben."
 echo ""

else

#  if [ $2="" ]
#  then

#    echo ""
#    echo "Bitte eine neue Bildgröße, z.B. \"640x480\", als zweiten Parameter angeben."
#    echo ""

#  else

#    if [ $3="" ]
#    then $3="kleiner"

#    elif [ $4="" ]
#    then $4="kl-"

#    elif [ $5="" ]
#    then $5=$1

#  fi

  mkdir ./$3

  for i in *.$1
  do convert $i -resize $2 ./$3/$4${i%.*}.$5
  done

  echo "Alle $1-Bilder im aktuellen Verzeichnis wurden auf $2 (x/y) Pixel und in $5 konvertiert und im"
  echo "Verzeichnis \"$3\" mit dem Präfix \"$4\" abgelegt."
  echo ""

#  fi

fi

Hallo,

die Basis des Scripts funktionierte. Doch als ich ein paar ifs eingebaut habe, ignoriert das script die Parameter.. bin Anfänger und wollte mir ein kleines Script basteln, mit dem ich bequem die Bilder eines Ordners konvertiere und in einem anderen Ordner speichere.

Sieht jemand, wo das Problem liegt? ein " zuviel?

Später wollte ich evtl. ein Script erstellen, das im Nautilus-Script-Ordner funktioniert.. Da klappt das leider mit den Parametern nicht, oder?

Danke schon einmal,
W.
 
hallo wilder,

ich habe vor kurzem mir folgendes script dazu ersonnen:
Code:
#rescale

#script to easyly mass rescale a colleection of jpeg, bitmap or png pictures
#requieres ImageMagick

#Comes with the package Bash-Tools
#Ideas collected by Mendel Cooper (Advanced Bash Scripting Guide)
#Rewritten for opensuse 10.2 by Matthias Propst

#!/bin/bash

#VARS
NO_CONVERT=33
NO_ARG=65
WRONG_SIZE=80
#VARS

check_convert () #convert is a function for manipultating images. it comes with ImageMagick
{
VERSION=$(convert -version 2> /dev/null || echo "-" )

if [[ $VERSION == "-" ]]
then
echo "ImageMagick seemed not to be installed"
echo "Please install ImageMagick and rerun again."
echo "Script exits now."
drop_failure
exit $NO_CONVERT
else
echo "found $VERSION"
drop_ok
check_arg
fi
}

check_arg ()
{
if [ -z  $PIC ] 2> /dev/null
then
echo "You must at least select one file "
echo "Usage: `basename $0` \"[jpeg] [bmp] [gif] [png] [tif]\" "
drop_failure
exit $NO_ARG
else
echo "These Pictures have been selected for rescale"
for pic in $PIC
do
echo $pic
done
drop_ok
geometry
fi
}

geometry ()
{
read -p "Please specify the new horizontal size:" HOR
read -p "Please specify the new vertical size:" VERT
check_geometry
}

#check whether the input variables are valid integers
check_geometry ()
{
PIXEL=$(( $HOR * $VERT )) || PIXEL=0

if [ $PIXEL -eq 0 ]
then
echo "$HOR"x"$VERT" "is not a geometirc size"
drop_failure
exit $WRONG_SIZE
else
main
fi
}

main ()
{
for pic in $PIC
do
unset PICS_S
PICS_S=$(identify -verbose $pic|grep Geometry)  || PICS_S="-"
if [ $PICS_S == "-" ] 2> /dev/null
then
echo "$pic seems not to have a valid format"
echo -e '\E[33mskipped'; tput sgr0
else
unset OLD_GEO
unset A
unset OLD_HOR
unset OLD_VERT
unset OLD_PIXEL
OLD_GEO=$(echo ${PICS_S##* })
A=$(echo ${OLD_GEO%%x*})
declare -i OLD_HOR=$(echo ${A##* })
declare -i OLD_VERT=$(echo ${PICS_S##*x})
OLD_PIXEL=$(( $OLD_VERT * $OLD_HOR ))
	if [[ $PIXEL -ge $OLD_PIXEL ]]
	then
	echo "The pic allready has $OLD_PIXEL pixel but you want to rescale to $PIXEL pixel, which is greater or equal than the original size."
	echo -e '\E[33mskipped'; tput sgr0
	else
	convert $pic -verbose -scale "$HOR"x"$VERT" rescale_new-$pic
	fi
fi
done
}

drop_ok ()
{
echo -e '\t \t \t \t \E[32mok'; tput sgr0
}

drop_failure ()
{
echo -e '\t \t \t \t \E[31mfailure'; tput sgr0
}

PIC=$*
case $1 in
-i)
for pic in $PIC
do

identify -verbose $pic 2> /dev/null |grep Geometry 2> /dev/null && ls $pic
done;;
*) check_convert
esac

exit 0

hilft dir das erst einmal weiter?
 
hallo und danke,
das ist ja schon einmal etwas umfangreicher. aber fürs erste, auch damit ich die bash besser verstehe, wäre mir ein einstieg mit meinem script lieber. in kleinen schritten also. :)

also erst den fehler in meinem scriipt finden. anschließend kann ich mir auch dein script näher anschauen. bisher für mich teils sehr kryptisch..

gruß, w.
 
*kommentar reinschmeiß*

Um einen String auf "Gefülltheit" respektive "Leerheit" (O_o) zu prüfen, kann man die '-z' Option von test verwenden:
man test schrieb:
-z STRING
the length of STRING is zero

Beispiel:
Code:
leer=""
if [ -z "$leer" ]; then
    echo 'Die Variable ist leer.'
else
    echo 'Die Variable ist nicht leer.'
fi
# Ausgabe: Die Variable ist leer.
Respektive, um auf "Befülltheit" (0ô) zu überprüfen einfach die Bedingung negieren:
Code:
foo="hihi"
if [ ! -z "$foo" ]; then
    echo 'Die Variable ist nicht leer.'
else
    echo 'Die Variable ist leer.'
fi
# Ausgabe: Die Variable ist nicht leer.

Es würde auch mit dem Vergleichsoperator funtionieren, aber dann müsstest du Leerzeichen zwischen die zu Vergleichenden Strings setzen.
Außerdem funktioniert das hier nicht:
Code:
$1="zomg"
1. Kannst du afaik nicht einfach die dem Skipt übergebenen Parameter neu zuweisen.
2. Müsstest du das '$' weglassen, wenn du einer Variable einen Wert zuweisen willst.
Dieses Problem könnte man geschickter lösen. Zum Beispiel mit einer Variable mit default-Wert, die den Wert des ersten Parameters zugewiesen bekommt, insofern dieser nicht leer ist:
Code:
#!/bin/bash
ERSTES_ARGUMENT="zomg, ich bin der default wert :0"
if [ ! -z "$1" ]; then ERSTES_ARGUMENT="$1"; fi
echo $ERSTES_ARGUMENT
I'm all out of ideas now. Den Rest (den nicht auskommentierten) hab ich mir noch nicht wirklich angesehen.
 
Zuletzt bearbeitet:
0o
tuxlover schrieb:
schön aber das weiß ich auch schon und wie unterdrückst du dann den stderr?
you talkin to me?

Weil ich habe nämlich nicht mir dir, sondern mit dem Threadersteller geredet und mir sein Skript angeschaut. Ich dachte, dass wäre ersichtlich gewesen…

Achja, und in answer to your question:
Code:
2>/dev/null
:d *n eis back*
 
Hallo und vielen Dank! Habe noch mehrere kleinere Fehler ausgemerzt und es funktioniert jetzt. :)

Ich habe aber noch ein paar Verständnisfragen.

(1) Die variable -z kommt vom Programm test. Woher weiß die if-Abfrage, dass diese von test gemeint ist? Woher bekomme ich andere Parameter, die in der if-Abfrage funktionieren. Kann man ja scheinbar alle über die man-Pages herausfinden, wenn man weiß welchem Programm der Parameter zuzuordnen ist.

(2) if ist auch ein Programm ?

(3) Dürfen bei einer Zuweisung keine Leerzeichen dazwischen sein? z.B. VAR="Text" und nicht VAR = "Text"
Funktioniert nur VAR1="$VAR2" und VAR1=$VAR2 nicht (ohne ")?

hier mein neuer Code:

Code:
#!/bin/sh

# prüft, ob $1 leer ist. wenn ja, dann Fehlermeldung.
if [ -z "$1" ] 
then

  echo ""
  echo " bildklein [dateityp-1] [größe] [verzeichnis] [präfix] [dateityp-2]"
  echo " --------------Nötige Parameter---------------------------------------------"
  echo " dateityp-1  * z.B. jpg, png, gif, tif: Von alle Datei diese Dateityps im"
  echo "               aktuellen Verzeichnis werden Verkleinerungen angelegt."
  echo " größe       * z.B. 640x480: Welche Pixelbreite und -höhe (X/Y) sollen die"
  echo "               neuen Bilder haben. Auch nur Breite (X) angeben möglich."
  echo " --------------Mögliche Parameter-------------------------------------------"
  echo " verzeichnis * Den Namen für das Unterverzeichnis, in dem die neuen Bilder"
  echo "               abgespeichert werden sollen."
  echo " präfix      * z.B. klein-: Welches Präfix sollen die verkleinerten Bilder"
  echo "               erhalten."
  echo " dateityp-2  * Welchen Dateityp sollen die neuen verkleinerten Bilder haben."
  echo " ---------------------------------------------------------------------------"
  echo ""

else

  # prüft, ob $2 leer ist. wenn ja, dann Fehlermeldung.
  if [ -z "$2" ]; then

    echo ""
    echo "Bitte eine neue Bildgröße, z.B. \"640x480\", als zweiten Parameter angeben."
    echo ""

  else

  verzeichnis="$3"
  praefix="$4"
  dateityp2="$5"

  # prüft, ob $3 leer ist. wenn ja, dann Verzeichnisname gleich "kleiner"
  if [ -z "$verzeichnis" ]; then verzeichnis="kleiner"; fi

  # prüft, ob $4 leer ist. wenn ja, dann Päfix gleich "kl-"
  if [ -z "$praefix" ]; then praefix="kl-"; fi

  # prüft, ob $5 leer ist. wenn ja, dann Dateityp-2 gleich Dateityp-1
  if [ -z "$dateityp2" ]; then dateityp2="$1"; fi

  mkdir ./"$verzeichnis"

  for i in *.$1
  do convert $i -resize $2 ./$verzeichnis/$praefix${i%.*}.$dateityp2
  done

  echo "Alle \"$1\"-Bilder im aktuellen Verzeichnis wurden auf $2 Pixel (x/y)"
  echo "verkleinert und in \"$dateityp2\"-Bilder konvertiert und im Verzeichnis \"$verzeichnis\""
  echo "mit dem Präfix \"$praefix\" abgelegt."
  echo ""

  fi

fi

ach so, habe ein Script-Verzeichnis und dieses in die Umgebungsvariable eingefügt.
Im Home-Verzeichnis die .bashrc geöffnet und diese Zeile eingefügt:
Code:
export PATH=$PATH:/home/user/script-verz:/home/user/anderesVerz:/home/user/drittesVerz
?? muss die Zeile mit einem Semikolon abschließen?
 
Zuletzt bearbeitet:
Ich nehme weiterhin die Verwendung von bash an, ist aber quasi auch auf andere shells anwendbar.
Zu den Verständnisfragen:

ad (1): '-z' ist keine Variable, sondern eine Option vom Programm 'test'. Um alle möglichen Optionen sowie Syntax nachzulesen, reicht ein 'man test'.
Diese Schreibweise hier:
Code:
if [ -z "$bla" ] …
ist nur eine syntaktische Sahnehaube, die nichts anderes bedeutet, als exakt dieses hier:
Code:
if test -z "$bla" …
Allerdings ist das erste einfacher zu lesen und schneller zu schreiben.

ad (2): nein, if ist ein bash-buildin Kommando(also gehört es zum Programm "bash" und ist damit keine "eigenes" Programm). Es prüft (afaik) den returncode des Programmes, welches "dahinter" steht. Wenn dieses Programm erfolgreich terminiert, ist die Bedingung wahr. Allerdings lässt if mehrere Verzweigungen mit "elif" und "else" zu, sodass if "mächtiger", oder zumindest klarer lesbar ist als die Bedingungen mit "&&" (voriges Programm terminierte erfolgreich) und "||" (voriges Programm terminierte mit einem Fehler).

ad (3): nein, bei einer Zuweisung dürfen keine Leerzeichen vorkommen.
VAR1="$VAR2" und VAR1=$VAR2 <- beides funktioniert, aber wenn du VAR2 nicht quotest (mit double quotes, single quotes würden die Variablenexpansion verhindern), werden bestimmte Sonderzeichen nicht "entwertet". Also wenn VAR2 ein Asterisk enthalten würde (auch Sternchen genannt, dieses Zeichen hier: *), so würde die bash (versuchen) dieses Asterisken mit möglichen Datei- und Verzeichnisnamen im aktuellen Verzeichnis zu expandieren. Mach mal:
Code:
echo *
und:
Code:
echo "*"
um den Unterschied zu verstehen. Steht übrigens auch alles in 'man bash' :0

edit: nein, die Zeile muss nicht mit einem semicolon abgeschlossen werden. So wie keine Zeile in der bash. Semicola sind dazu da, um mehrere Kommandos in der selben Zeile zu separieren, du verwendest aber nur ein einziges Komanndo, also…
 
Zuletzt bearbeitet:
ich verweise dazu auch gerne mal wie immer auf http://tldp.org/LDP/abs/html/.

Man sollte sich ruhig mal die mühe machen und anfangen das durchzuarbeiten. ist glaube ich der beste weg, um shell prograammierung zu lernen und so ein paar sachen von dem was auch in man bash steht besser zu verstehen.
auch wenn man am anfang nicht alles versteht. das kommt mit der zeit.


ich finde es auch etwas viel verlangt gleich die ganze manpage zur bash durchzulesen. spätestens nach 100 zeilen hat man keine lust mehr dazu. sie ist meinern meinung nach auch eher als ergänzende hilfe und nicht als abendlektüre gedacht.
 
@ tuxlover:
tuxlover schrieb:
ich finde es auch etwas viel verlangt gleich die ganze manpage zur bash durchzulesen.
ich weiß echt nicht, ob ich weinen oder lachen soll…
Ach, ich lache einfach mal: LOL

Ich habe ihm zu jeder Frage eine ausführliche für Anfänger verständliche Antwort geliefert und am Ende zusätzlich darauf hingewiesen, dass diese Infos auch in der man-page sind 0o
Die bash-manpage ist zum Nachschlagen, sie ist keinesfalls als "Tutorial" oder "Lehrbuch" gedacht, was ich auch an keiner Stelle gesagt/angedeutet whatever habe O_o

btw verstehe ich auch deine sonstigen Posts in diesem thread (ausgenommen vielleicht mal das gepostete Skript am Anfang) nicht. Was willst du die ganze Zeit vonwegen Fehlerkanal umleiten? 0ô
Ich meine, man kann den Fehlerkanal umleiten, schon klar, manchmal ist das sinnvoll und bla, aber was genau, um Himmels Willen, hat das mit der Fragestellung vom Threadersteller zu tun? oO
 
ad (1): '-z' ist keine Variable, sondern eine Option vom Programm 'test'. Um alle möglichen Optionen sowie Syntax nachzulesen, reicht ein 'man test'.
Diese Schreibweise hier:
Code:
if [ -z "$bla" ] …
ist nur eine syntaktische Sahnehaube, die nichts anderes bedeutet, als exakt dieses hier:
Code:
if test -z "$bla" …
Allerdings ist das erste einfacher zu lesen und schneller zu schreiben.

vielen dank, das war aufschlussreich. doch ein detail ist mir noch nicht ganz klar geworden. diese option -z von test muss if dem programm test zuordnen können, damit if weiß, was mit -z gemeint ist. woher weiß if, dass die option -z dem programm test zuzuordnen ist? wenn nur if [ -z "$bla" ] im code steht. es könnte ja auch heißen if echo -z "XXX" oder if ls -z (ok, diese haben keine option z, aber mal angenommen).

gruß,w.
 
Hallo
Diese (eckige) Klammer
Code:
if [b][[/b] -z  foo ];then ...
ist ein Alias auf test!

Gruß Wolfgang
 
danke für den hinweis. damit wäre für mich das thema geklärt.
 

Ähnliche Themen

Switche abfragen über Script

NAS-Drive Mount in Bash-Script über crontab

script sshpass

Verschlüsseltes Backup-Script mit rsync

HandbrakeCLI Shell Skript

Zurück
Oben