2016-07-26 24 views
1

Ich habe eine .csv Datei, in der etwa wie folgt aussieht:anpassen Datei Skript umbenennen, so dass es jede Datei in Unterverzeichnissen aufspürt

unnamed_0711-42_p1.mov,day1_0711-42_p1.mov 
unnamed_0711-51_p2.mov,day1_0711-51_p2.mov 
unnamed_0716-42_p1_2.mov,day1_0716-42_p1_2.mov 
unnamed_0716-51_p2_2.mov,day1_0716-51_p2_2.mov 

ich diesen Code geschrieben haben, Dateien aus dem Namen im Feld umbenennen 1 (zB), auf den Namen in Feld 2 (zB day1_0711-42_p1.mov).

Dieses Skript funktioniert jedoch nur, wenn es und alle Dateien, die umbenannt werden müssen, sich im selben Verzeichnis befinden. Das war vorher okay, aber jetzt muss ich Dateien in verschiedenen Unterverzeichnissen finden (ohne den vollständigen Pfad zu meiner .csv Datei hinzuzufügen).

Wie kann ich mein Skript so anpassen, dass es die Dateien in Unterverzeichnissen sucht und dann den Namen wie zuvor ändert?

+0

Können Sie die erste Zeile umformulieren, die nicht klar ist? – sjsam

+0

bearbeitet, hoffe, das ist klarer. – neilH

+0

Wo ist der Ort 'unnamed_0711-42_p1.mov'. Ist dies derselbe Ort, an dem das Skript ausgeführt wird? – sjsam

Antwort

1

tun Eine einfache Möglichkeit, diese Arbeit zu machen, wenn es zu einer ineffizienten Skript führt, ist dies:

Dies wird Ihren Befehl für jedes Verzeichnis im aktuellen Verzeichnis ausführen, aber dies läuft durch die gesamte Liste der Dateinamen für jedes Unterverzeichnis. Eine Alternative wäre für jede Datei zu suchen, wie Sie seinen Namen verarbeiten:

csv=files.csv 
while IFS=, read -ra arr; do 
    while IFS= read -r -d '' old_file; do 
     old_dir=$(dirname "$old_file") 
     mv "$old_file" "$old_dir/${arr[1]}" 
    done < <(find . -name "${arr[0]}" -print0) 
done<"$csv" 

Dies verwendet find jeden alten Dateinamen zu finden, verwendet dann dirname das Verzeichnis der alten Datei zu erhalten (die wir brauchen, damit mv tut die umbenannte Datei nicht in ein anderes Verzeichnis verschieben).

Dadurch wird jede Instanz jeder Datei umbenannt (d. H. Wenn unnamed_0711-42_p1.mov in mehreren Unterverzeichnissen angezeigt wird, wird jede Instanz in day1_0711-42_p1.mov umbenannt). Wenn Sie wissen, dass jeder Dateiname nur einmal angezeigt wird, können Sie die Dinge ein wenig beschleunigen, indem Sie am Ende des Suchbefehls vor der Pipe -print -quit hinzufügen.

+0

Dies scheint nicht zu funktionieren, nur um zu klären, für "dirname" sollte ich die oberste Ebene/Master-Ordner, unter dem alle Dateien befinden (in Unterverzeichnissen) richtig? – neilH

+0

./rename.sh: Zeile 7:/DG1440/tester_delete/anotherlevel: Ist ein Verzeichnis mv: kann keine reguläre Datei '/day63_testday2p1_0929-36_p1.mov 'erstellen: Berechtigung verweigert – neilH

+0

@ bms9nmh Nein," dirname "ist ein Befehl. Das einzige, was Sie in dem Skript, das ich zur Verfügung gestellt habe, bearbeiten sollten, ist der Name Ihrer CSV-Datei. – SnoringFrog

1

Below Skript

while IFS=, read -ra arr # -r to prevent mangling backslashes 
do 
find . -type f -name "${arr[0]}" -printf "mv '%p' '%h/${arr[1]}'" | bash 
done<csvfile 

sollte es tun.


Siehe [ find ] manpage zu verstehen, was die printf Bezeich wie% p,% h

+0

Hallo sjjam, das hat nicht funktioniert, ich bekomme einen Fehler für jede Datei "mv: kann nicht stat' examplefillename.mov ': Keine solche Datei oder Verzeichnis ". Ich glaube nicht, dass dieser Code rekursiv recherchiert, er scheint nur in dem Verzeichnis zu suchen, in dem sich das Skript befindet. – neilH

+0

Dies verarbeitet die Paare aus der '.csv'-Datei nicht richtig. Das Hinzufügen eines "Echos" vor dem "mv" macht dies leicht ersichtlich. – SnoringFrog

+0

@ bms9nmh: Ich habe meine Antwort aktualisiert. Bitte guck dir das an. – sjsam