2016-04-26 10 views
0

Problem beim Massenumbenennen von Dateien in einem Pfad.Massenumbenennung von zufällig benannten Dateien, ohne deren Pfad zu kennen

Hier ist mein Problem: Ich habe ein Laufwerk voller rund 16000 oder mehr Dateien (alle Bilder, aber möglicherweise .psd, .jpg, .ai, .png, etc) verstreut in einer sehr chaotischen Art und Weise, aber die Dateinamen sind glücklicherweise alle einzigartig, aber aufgrund der Menge, kann ich nicht sagen, dass das sicher ist (ich meine, es könnte 2 Dateien namens abc.ai oder das Äquivalent, aber nicht viele). Ich kann den Pfad nicht kennen, da der bereitgestellte csv nur die ursprünglichen Dateinamen enthält und in die sie umbenannt werden sollten.

Grundsätzlich ist die erste Zeile in der CSV ist so etwas wie:

qwerty.jpg, asdfg.jpg

oder

123-asd_qwe.ai, abcfgd. ai.

Ich habe mehrere Lösungen, die ich gefunden habe, versucht; sed, einige Skripte, alles, was ich ausprobieren konnte, tat ich wirklich.

Ich würde wirklich gerne Vorschläge oder Ideen oder sogar eine Lösung zu hören!

Zu beachten: i ::

sed 's/"//g' names.csv | while IFS=, read orig new; do echo mv "$orig" "$new"; done 

und

sed 's/^/mv -i -v "/;s/, /" "/;s/$/";/' < names.csv | bash - 

und

#!/bin/bash 
while read line   
do   
     OldImageName=${line%,*} 
     NewImageName=${line#*,} 
     mv "$OldImageName" "$NewImageName" 
done <"names.csv" 
+0

Warum ersetzen Sie alle doppelten Anführungszeichen durch nichts im sed-Befehl? Ich kann keine Anführungszeichen in der Datei sehen. – 123

+0

Ich habe es versucht. Nur für den Fall, dass die gigantische CSV-Datei solche haben würde. – frosty

Antwort

0

Dies ist die vollständige Lösung, die in dem oben beschriebenen spezifischen Fall funktioniert - Es berücksichtigt doppelte Dateien (in verschiedenen Ordnern) und auch die Benennung der Dateinamen (Leerzeichen, Akzente, etc.) haben keine Auswirkungen auf das Skript . Siehe Lösung unten:

DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 

while read line 
do 
    OldImageName=$(echo $line | cut -d "," -f 1) 
    NewImageName=$(echo $line | cut -d "," -f 2) 

    isMatchRelativePath=$(echo $(find . -name "$OldImageName")); 
    isMatchNewName=$(echo $(find . -name "$NewImageName")); 

    if [ ! -z "$isMatchRelativePath" ]; 
    then 

     find . -name "$OldImageName" -print0 | while read -d $'\0' file 
     do 

     relativeFolder="${file%$OldImageName}" 

     quote1="$relativeFolder$OldImageName"; 
     quote2="$relativeFolder$NewImageName"; 

     mv "${quote1}" "${quote2}" 
     echo "$relativeFolder$OldImageName, $relativeFolder$NewImageName">>"$DIR/success.csv" 
     done 


    elif [ ! -z "$isMatchNewName" ]; then 
     echo "alreadyRenamed" 
     echo "$relativeFolder$OldImageName, $relativeFolder$NewImageName">>"$DIR/alreadyRenamed.csv" 
    else 
     echo "failed" 
     echo "$relativeFolder$OldImageName, $relativeFolder$NewImageName">>"$DIR/failed.csv" 
    fi 

done <input.csv 
+0

Das war. Perfekt. – frosty

2

versucht Wenn Sie absolut sicher der Art und Weise sind die names.txt die Namen in das hätte Bestellung oldname,newname dann sollte die folgende Logik ausreichen: -

#!/bin/bash 

while read line 
do 
     # Splitting the line with delimiter as ',' and 
     # getting the fields before and after 

     OldImageName=$(echo $line | cut -d "," -f 1) 
     NewImageName=$(echo $line | cut -d "," -f 2) 

     if [ $(find . -name "$OldImageName" | wc -l) -gt 0 ]; then 

      # Get the absolute path of the file 

      path=$(dirname $(readlink -f "$OldImageName")) 

      # Verbose option '-v' for verifying the file rename and 
      # to suppress errors if file not present 

      mv -v "$path/$OldImageName" "$path/$NewImageName" 2>/dev/null 
     fi 

done <names.csv 
+0

Das Problem dabei ist, dass ich Schwierigkeiten habe zu wissen, wo sich die Dateien befinden. Pfade sind nicht bekannt. – frosty

1

(Neu geschrieben die Antwort, nachdem die Frage in den Kommentaren geklärt wurde).

Die erste Lösung funktioniert nur, wenn Ihre CSV-Datei ganze Pfade enthält, nicht nur Basisnamen. Sie müssen es durchlaufen, jede Datei finden und umbenennen.

sed -r 's/, ?/\t/' names.csv | while IFS=$'\t' read orig new; do 
    find $DIR -type f -name "$orig" | while read path; do 
     dirname=`dirname "$path"` 
     target_path="$dirname/$new" 
     if [[ ! -f "$target_path"]]; then 
     mv -v -- "$path" "$target_path" 
     else 
     echo "Could not rename '$path' to '$target_path'. Target file exists" >&2 
     fi 
    done 
done 

ersetzen $DIR mit dem obersten Verzeichnis. Hinweis: Ich gehe davon aus, dass jeder Basisname mit einer Anzahl von Dateien in verschiedenen Verzeichnissen übereinstimmen kann. Deshalb iteriere ich die Ausgabe von find.

+0

Ich habe Ihre Lösungen versucht; Das Problem ist, dass mein csv im Stammordner existiert, während die Dateien irgendwo von diesem Stammordner existieren können. Also muss ich einen Weg finden, nach Dateien von ROW-N zu suchen: COLUMN-1, benenne es in ROW-N um: COLUMN-1; Bedeutet, dass ich in der Lage sein sollte, einen ziemlich großen csv ideal zu parsen; Finde, wo die Datei (erste Spalte jeder Zeile) ist (find, locate, grep?); Benenne es dann um (basierend auf dem Wert aus derselben Zeile, aber in Spalte 2). Wirklich verloren, wie das herauszufinden. – frosty

+1

Das Entfernen von doppelten Anführungszeichen aus Ihren Erweiterungen ist keine Lösung, sondern eine Möglichkeit, etwas nur für kurze Zeit zu beheben. Solch ein Code kann nicht richtig gepflegt werden, ist nicht tragbar und gefährlich. Anstatt zwei Probleme zu behandeln, indem Sie separate Lösungen bereitstellen, sollten Sie beide gleichzeitig behandeln. Erstellen Sie einen robusten Code. Ich würde auch vorschlagen, 'mv" $ orig "" $ new "' zu 'mv -" $ orig "" $ new "' zu ändern, so dass optionsähnliche Dateinamen (zB '-m MODE') gewonnen ' t in der Lage sein, das Verhalten von 'mv' zu ändern. Außerdem - [Useless Use of Cat] (http://porkmail.org/era/unix/award.html). –

+0

@frosty Bitte sag mir, ob ich dein Problem jetzt richtig verstanden habe. Die CSV-Datei enthält nur die Informationen zum ursprünglichen Basisnamen und zum Zielbasisnamen. Die Aufgabe besteht darin, die Datei anhand ihres Basisnamens zu finden und sie umzubenennen, ohne ihr Verzeichnis zu ändern. –

Verwandte Themen