PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : script verschlingt daten



Apollon
06-01-2008, 10:06
Hallo Leute.
hab folgendes Script geschrieben. Es hat die
Aufgabe alle jpg.'s in eine geordnete Form
zu bringen (001-009, 010-099, 100-...).

--------------------------------------------------
#!/bin/bash

j=0

for i in $(ls|grep .jpg); do
let j=$j+1;

if [ $j -lt 10 ]; then
mv $i 00$j.jpg;
fi;

if [ $j -ge 10 ]; then
if [ $j -lt 100 ]; then
mv $i 0$j.jpg;
fi;
fi;

if [ $j -ge 100 ]; then
mv $i $j.jpg;
fi;

done
--------------------------------------------------

Es scheint auch einigermaßen zu funktionieren.
Das Problem ist nur dass es Daten vernichtet. Es
fehlen die Bilder von 002.jpg bis 010.jpg.
Demzufolge müsste ja die erste if-Abfrage defekt
sein. Ich kann den Fehler nur nicht entdecken.
Und noch was - könntet ihr mir eine elegantere
Methode zeigen um entsprechend viele Nullen
an eine Zahl zu hängen damit am ende alle gleich
viele Ziffern haben?

Danke fürs Lesen.
Hoffe auf Antwort.

rais
06-01-2008, 19:37
Hallo und Herzlich Willkommen :)


Das Problem ist nur dass es Daten vernichtet. Es
fehlen die Bilder von 002.jpg bis 010.jpg.

das kann ich zwar nicht nachvollziehen, aber etwas anders angehen würd ich's trotzdem - uA damit sich das Skript nicht blind darauf verlässt, daß die Bilder auch wirklich alle da sind;-)


#!/bin/bash
# foo[.sh]
X=$1
test -z "$X" && X="0000"
for I in *.jpg; do
J=${I%.jpg} #erstmal .jpg abschneiden
LI=${#J} #davon dann die Länge nehmen
LX=${#X} #sowie von der Zielbreite
if [ $LI -lt $LX ]; then #nur wenn Länge<Zielbreite
XP=$LX-$LI
mv $I ${X:0:$XP}$J.jpg
fi
done

dazu erstmal ein paar Bilder gebaut:


declare int i=0; while [ $i -lt 100 ]; do let i=$i+1; touch $i.jpg; done
ls
100.jpg 20.jpg 31.jpg 42.jpg 53.jpg 64.jpg 75.jpg 86.jpg 97.jpg
10.jpg 21.jpg 32.jpg 43.jpg 54.jpg 65.jpg 76.jpg 87.jpg 98.jpg
11.jpg 22.jpg 33.jpg 44.jpg 55.jpg 66.jpg 77.jpg 88.jpg 99.jpg
12.jpg 23.jpg 34.jpg 45.jpg 56.jpg 67.jpg 78.jpg 89.jpg 9.jpg
13.jpg 24.jpg 35.jpg 46.jpg 57.jpg 68.jpg 79.jpg 8.jpg foo
14.jpg 25.jpg 36.jpg 47.jpg 58.jpg 69.jpg 7.jpg 90.jpg foobar
15.jpg 26.jpg 37.jpg 48.jpg 59.jpg 6.jpg 80.jpg 91.jpg foobar.sh
16.jpg 27.jpg 38.jpg 49.jpg 5.jpg 70.jpg 81.jpg 92.jpg foo.sh
17.jpg 28.jpg 39.jpg 4.jpg 60.jpg 71.jpg 82.jpg 93.jpg
18.jpg 29.jpg 3.jpg 50.jpg 61.jpg 72.jpg 83.jpg 94.jpg
19.jpg 2.jpg 40.jpg 51.jpg 62.jpg 73.jpg 84.jpg 95.jpg
1.jpg 30.jpg 41.jpg 52.jpg 63.jpg 74.jpg 85.jpg 96.jpg

wie wär's fünfstellig?


./foo 00000
ls
00001.jpg 00016.jpg 00031.jpg 00046.jpg 00061.jpg 00076.jpg 00091.jpg
00002.jpg 00017.jpg 00032.jpg 00047.jpg 00062.jpg 00077.jpg 00092.jpg
00003.jpg 00018.jpg 00033.jpg 00048.jpg 00063.jpg 00078.jpg 00093.jpg
00004.jpg 00019.jpg 00034.jpg 00049.jpg 00064.jpg 00079.jpg 00094.jpg
00005.jpg 00020.jpg 00035.jpg 00050.jpg 00065.jpg 00080.jpg 00095.jpg
00006.jpg 00021.jpg 00036.jpg 00051.jpg 00066.jpg 00081.jpg 00096.jpg
00007.jpg 00022.jpg 00037.jpg 00052.jpg 00067.jpg 00082.jpg 00097.jpg
00008.jpg 00023.jpg 00038.jpg 00053.jpg 00068.jpg 00083.jpg 00098.jpg
00009.jpg 00024.jpg 00039.jpg 00054.jpg 00069.jpg 00084.jpg 00099.jpg
00010.jpg 00025.jpg 00040.jpg 00055.jpg 00070.jpg 00085.jpg 00100.jpg
00011.jpg 00026.jpg 00041.jpg 00056.jpg 00071.jpg 00086.jpg foo
00012.jpg 00027.jpg 00042.jpg 00057.jpg 00072.jpg 00087.jpg foobar
00013.jpg 00028.jpg 00043.jpg 00058.jpg 00073.jpg 00088.jpg foobar.sh
00014.jpg 00029.jpg 00044.jpg 00059.jpg 00074.jpg 00089.jpg foo.sh
00015.jpg 00030.jpg 00045.jpg 00060.jpg 00075.jpg 00090.jpg

MfG,

jan61
07-01-2008, 20:06
Moin,

eine Bitte: formatiere Scripts bitte mit dem code-Tag, das macht es einfacher lesbar (und rücke vielleicht ein wenig ein, dann sieht es noch besser aus).

Auf den ersten Blick kann ich auch keinen Fehler entdecken. Mein Standard-Tipp: Setze an den Anfang des Scripts ein "set -x", dann siehst Du jeden Befehl, den es ausführt.

Ich habe auch noch eine Variante, die ein wenig kürzer ist:

# Test-Dateien anlegen - nur fuer Demo!
for i in `seq 1 1000`; do touch ${i}.jpg; done
# gewuenschte Ausgabebreite
b=4
# jetzt die Schleife
for i in `ls [0-9]*.jpg`; do
n=`printf "%0${b}d" \`basename $i .jpg\``.jpg
test -f $n || mv $i $n
doneJan

EDIT: Die maximal notwendige Breite kann man natürlich auch ermitteln lassen, hier mal 2 Varianten:

b=`expr \`ls *.jpg | sed 's/\.jpg$//' | sort -n | tail -1 | wc -c\` - 1`
b=`expr \`ls *.jpg | awk ' {if(length($1)>l) l=length($1);} END {print l;}'\` - 4`Variante 1 ist kürzer, Variante 2 braucht weniger Pipes ;-)

EINEN hab ich noch ;-) Es geht auch ganz ohne Schleife. Nachfolgender Befehl lässt einfach durch einen find die Kommandozeile zusammenbasteln und übergibt sie dann einer Shell zur Ausführung:
find . -type f -name '[0-9]*.jpg' -printf 'mv -u %p %h/`printf "%%0'$b'd.jpg" \\`basename %f .jpg\\``\n' | shDabei wird die -u-Option des mv etwas zweckentfremdet benutzt. Das Schöne an der Zeile ist die Tatsache, dass diese Variante auch rekursiv funktioniert; ausserdem gibts keinen Stress mehr, wenn die Anzahl der Dateien den Puffer für die Eingabezeile sprengt ("argument list too long"). Passenderweise modifiziert man dann die o. a. Zeilen für die Ermittlung von $b auch so, dass sie statt ls den find nutzen.

Apollon
07-01-2008, 22:44
Hey,
möchte mich bedanken - hab viel neues gelernt.
Werde in Zukunft auch den Code-Tag verwenden ;-)
Und ein zweites mal scheint es diesen Fehler auch
nich gegeben zu haben (bei mir, habs ausprobiert).
Naja, egal. Also dann.

Machts gut und Danke nochmal.