scripting - Doppelte Dateien finden, falls Ordner auf case-insensitive FS kommt
Hallo!
Mein Problem ist schwierig zu beschreiben, daher hat mir google auch nicht geholfen.
Ich versuche es mal: In einem Ordner liegen mehrere Dateien, beispielsweise: a.jpg,
g.jpg, A.jpg, G.jpg. Bei einem case-sensitive-Dateisystem (es kommt auf
Groß-/Kleinschreibung an) kein Problem.
Wird aber der Ordner auf ein case-insensitive-Dateisystem (Groß-/Kleinschreibung egal)
kopiert, werden die Dateien entweder nicht kopiert, oder überschrieben.
Hier meine Idee: Die "doppelten" Dateien sollen beim Aufruf eines Scripts gefunden und
umbenannt werden, solange sie noch auf dem besseren Dateisystem sind.
Zurück zum Beispiel: Nach dem Script sollen etwa folgende Dateinen im Verzeichnis
liegen: a.jpg, g.jpg,a<zeichen>.jpg g
Hallo, 2006-05-24 12:11 +0200, Martin Ereth:
Hallo!
Mein Problem ist schwierig zu beschreiben, daher hat mir google auch nicht geholfen.
Ich versuche es mal: In einem Ordner liegen mehrere Dateien, beispielsweise: a.jpg, g.jpg, A.jpg, G.jpg. Bei einem case-sensitive-Dateisystem (es kommt auf Groß-/Kleinschreibung an) kein Problem. Wird aber der Ordner auf ein case-insensitive-Dateisystem (Groß-/Kleinschreibung egal) kopiert, werden die Dateien entweder nicht kopiert, oder überschrieben.
Hat jemand einen Gedanken zur Lösung?
Wie wäre's mit dem folgenden Skript: ---- cut here ---- LOWER='abcdefghijklmnopqrstuvwxyz' UPPER='ABCDEFGHIJKLMNOPQRSTUVWXYZ' declare -i COUNTER for source in * ; do # Change file name to lower case file=`echo "$source" | sed 'y/'$UPPER'/'$LOWER'/'` # Reset counter COUNTER=0 target="$file" if [ "$source" != "$target" ] ; then # Filename had got upper case characters if [ -e "$target" ] ; then # Target file already exist, insert counter # value to the beginning of the file name file="$COUNTER""$target" while [ -e "$file" ] ; do # Target file still exists -> Add counter by 1 and # insert counter value to the beginning of the file name COUNTER=$COUNTER+1 file="$COUNTER""$target" done target="$file" fi # Rename (move) file echo 'Renaming file: '"$source"' -> '"$target" mv "$source" "$target" else echo 'File name unchanged: '"$source" fi done ---- cut here --- Gruß Kimmo
K. Elo schrieb:
---- cut here ---- LOWER='abcdefghijklmnopqrstuvwxyz' UPPER='ABCDEFGHIJKLMNOPQRSTUVWXYZ' declare -i COUNTER for source in * ; do # Change file name to lower case file=`echo "$source" | sed 'y/'$UPPER'/'$LOWER'/'` # Reset counter COUNTER=0 target="$file" if [ "$source" != "$target" ] ; then # Filename had got upper case characters if [ -e "$target" ] ; then # Target file already exist, insert counter # value to the beginning of the file name file="$COUNTER""$target" while [ -e "$file" ] ; do # Target file still exists -> Add counter by 1 and # insert counter value to the beginning of the file name COUNTER=$COUNTER+1 file="$COUNTER""$target" done target="$file" fi # Rename (move) file echo 'Renaming file: '"$source"' -> '"$target" mv "$source" "$target" else echo 'File name unchanged: '"$source" fi done ---- cut here ---
Boah, so lang? Danke! Da hab ich ein paar Fragen: Die beiden Variablen UPPER und LOWER sind für sed. kann man sed nicht auch a-z bzw. A-Z übergeben? Oder das direkt zwischen die // schreiben? Warum wird COUNTER mit declare deklariert, und nicht erst wo es verwendest wird (counter=0)? Da sich die Sortierung der Dateien (Bilder) nicht ändern soll, sollte das $COUNTER nicht vor sondern hinter $file eingefügt werden, am besten mit einem _(unterstrich) dazwischen. Geht das? Was passiert mit Zahlen im Dateinamen? Wie groß darf COUNTER maximal werden? 65535? (Sprich die Anzahl doppelter Dateien im Verzeichnis) Danke für deine Arbeit! Viele Grüße Martin
Hallo Martin, 2006-05-24 14:05 +0200, Martin Ereth:
[...] Boah, so lang? Danke!
Na ja, sicherlich kann man das Skript auch optimieren...;-)
Da hab ich ein paar Fragen:
Die beiden Variablen UPPER und LOWER sind für sed. kann man sed nicht auch a-z bzw. A-Z übergeben? Oder das direkt zwischen die // schreiben?
Nein, s. 'man sed'.
Warum wird COUNTER mit declare deklariert, und nicht erst wo es verwendest wird (counter=0)?
Genauso gut kannst Du 'declare -i COUNTER=0' verwenden. Aus Gewohnheit deklariere ich die Variablen schon am Anfang. Übrigens, statt 'file' als Variablenamen sollte man lieber z.B. 'DATEI' benutzen. 'file' ist ja auch ein bash-Befehl...
Da sich die Sortierung der Dateien (Bilder) nicht ändern soll, sollte das $COUNTER nicht vor sondern hinter $file eingefügt werden, am besten mit einem _(unterstrich) dazwischen. Geht das?
Ich habe das Skript verändert, um dies zu erreichen: --- cut here --- LOWER='abcdefghijklmnopqrstuvwxyz' UPPER='ABCDEFGHIJKLMNOPQRSTUVWXYZ' for SOURCE in * ; do # Change DATEI name to lower case DATEI=`echo "$SOURCE" | sed 'y/'$UPPER'/'$LOWER'/'` # Reset counter declare -i COUNTER=0 TARGET="$DATEI" if [ "$SOURCE" != "$TARGET" ] ; then # Filename had got upper case characters if [ -e "$TARGET" ] ; then # TARGET file already exist, insert counter # value to the the file name DATEI=$([ `echo "$TARGET" | grep "\."` ] && ( echo "$TARGET" | sed 's/\./\_'"$COUNTER"'\./' ) || echo "$TARGET"_"$COUNTER") while [ -e "$DATEI" ] ; do # Target file still exists -> Add counter by 1 and # insert counter value to the file name COUNTER=$COUNTER+1 DATEI=$([ `echo "$TARGET" | grep "\."` ] && ( echo "$TARGET" | sed 's/\./\_'"$COUNTER"'\./' ) || echo "$TARGET"_"$COUNTER") done TARGET="$DATEI" fi # Rename (move) file echo 'Renaming file: '"$SOURCE"' -> '"$TARGET" mv "$SOURCE" "$TARGET" else echo 'File name unchanged: '"$SOURCE" fi done --- cut here --- Jetzt wird das COUNTER-Wert entweder vor den ersten Punkt (a.jpg -> a_#.jpg, #=COUNTER) oder - falls der Name keinen Punkt enthält am Ende (a -> a_#) hinzugefügt.
Was passiert mit Zahlen im Dateinamen?
Nichts: ~>LOWER='abcdefghijklmnopqrstuvwxyz' ~>UPPER='ABCDEFGHIJKLMNOPQRSTUVWXYZ' ~>echo "AbC1234.567" | sed 'y/'$UPPER'/'$LOWER'/' abc1234.567
Wie groß darf COUNTER maximal werden? 65535? (Sprich die Anzahl doppelter Dateien im Verzeichnis)
Es handelt sich um ein Integer. Ich vermute max. 32767.
Danke für deine Arbeit!
Gerne. War auch eine schöne Übung :-) Gruß Kimmo
participants (3)
-
K. Elo
-
Martin Ereth
-
Oliver Block