So benennen Sie mehrere Dateien in einem Verzeichnis gleichzeitig um

12

Ich habe Verzeichnis sagen, /var/tmp/abcdie 4 Dateien hat:

12345-ram-3e3r5-io9490-89adu9.csv
45434-dam-qwe35-to9490-43adu9.csv
11234-cam-yy3r5-ro9490-85adu9.csv
14423-sam-hh3r5-uo9490-869du9.csv

Ich möchte alle CSV-Dateien auf kürzestem Weg (wahrscheinlich einzeilig) umbenennen (alle Dateien finden und umbenennen):

XXXXX-ram-3e3r5-io9490-89adu9.csv
XXXXX-dam-qwe35-to9490-43adu9.csv
XXXXX-cam-yy3r5-ro9490-85adu9.csv
XXXXX-sam-hh3r5-uo9490-869du9.csv
Rocky86
quelle

Antworten:

15

rename -n 's/(\w+)/XXXXX/' *.csv

Entfernen Sie die, -nwenn Sie glücklich sind.

SHawarden
quelle
2
Für eine passende Version von rename. Ich nehme an, das ist Larry Walls rename, aus dem renamePaket in Debian und Derivat (und IIRC prenameauf Systemen der RedHat-Überzeugung). Ein sehr nützliches Werkzeug.
Magnet
2
perl-renamein arch linux
lesmana
1
@SHawarden, ich habe versucht, den Befehl auszuführen und den relevanten Teil der Manpage zu lesen, um das Ersetzungsmuster zu verstehen. Beim Hinzufügen des verboseFlags wird jedoch nichts ausgegeben und die Dateinamenänderungen werden nicht ausgeführt, obwohl der aktuelle Pfad dies enthält Dateien mit ähnlichen Namen 12345_foo.csv. Muss ich zusätzliche Aufgaben ausführen, damit es funktioniert (derzeit unter Fedora 30)? Es ist ein saubererer Ansatz als das Schleifen. Danke im Voraus!
Danieldeveloper001
3
@ danieldeveloper001 Hast du renameoder benutzt prename? Siehe meinen Kommentar oben. man {the command}listet die Autoren am Ende auf.
Magnet
2
Dies funktioniert nur auf von Debian abgeleiteten Systemen. Von Fedora abgeleitete Systeme haben einen völlig anderen renameBefehl. siehe unix.stackexchange.com/a/238862/135943
Wildcard
11

Versuchen:

for f in *.csv; do mv -i -- "$f" "XXXXX-${f#*-}"; done

Wie es funktioniert:

  • for f in *.csv; do

    Dies startet eine Schleife über alle *.csvDateien.

  • mv -i -- "$f" "XXXXX-${f#*-}"

    Hierdurch werden die Dateien nach Belieben umbenannt und vor dem Überschreiben einer Datei interaktiv gefragt.

  • done

    Dies markiert das Ende der Schleife.

Beispiel:

$ ls -1
11234-cam-yy3r5-ro9490-85adu9.csv
12345-ram-3e3r5-io9490-89adu9.csv
14423-sam-hh3r5-uo9490-869du9.csv
45434-dam-qwe35-to9490-43adu9.csv
$ for f in *.csv; do mv -i -- "$f" "XXXXX-${f#*-}"; done
$ ls -1
XXXXX-cam-yy3r5-ro9490-85adu9.csv
XXXXX-dam-qwe35-to9490-43adu9.csv
XXXXX-ram-3e3r5-io9490-89adu9.csv
XXXXX-sam-hh3r5-uo9490-869du9.csv
John1024
quelle
4

Die kleine Herausforderung, die Sie gepostet haben, hat mir gefallen. Hier ist meine Lösung. Ich gehe davon aus, dass alle Ihre Dateien mit 5 numerischen Zeichen beginnen. Verwenden Sie daher den Befehl cut , um die anfänglichen numerischen Dateien durch "XXXXX" zu ersetzen.

Unten die Dateien vor dem Befehl.

-rw-rw-r--. 1 daniel daniel 0 May 13 23:18 11111_bar_file.csv
-rw-rw-r--. 1 daniel daniel 0 May 13 22:54 12345_baz_file.csv
-rw-rw-r--. 1 daniel daniel 0 May 13 22:54 67890_foo_file.xml

Unten das Einzeiler-Kommando.

for src in *.csv; do dst=XXXXX$(echo $src| cut -c6-); mv $src $dst; done;

Unten die Dateien nach dem Befehl.

-rw-rw-r--. 1 daniel daniel 0 May 13 22:54 67890_foo_file.xml
-rw-rw-r--. 1 daniel daniel 0 May 13 22:54 XXXXX_bar_file.csv
-rw-rw-r--. 1 daniel daniel 0 May 13 23:18 XXXXX_baz_file.csv

Ist es das, wonach du suchst? :)

Verweise:

Durchlaufen der Befehlsausgabe in Bash

Teilstrings in bash

danieldeveloper001
quelle
2
Bash kann diese Art der String-Manipulation durchführen, es ist nicht erforderlich, für jeden einen neuen Prozess zu erstellen. Bitte geben Sie die andere Antwort, wie.
CHX
1
@chx, habe bereits die anderen Antworten gesehen und ein wenig Wissen daraus gewonnen, aber danke, dass Sie darauf hingewiesen haben. Würden Sie bitte näher darauf eingehen no need to fork a new process for each?
danieldeveloper001
3
cutist ein separates Binary ( /usr/bin/cut), dessen Ausführung mehr Ressourcen verbraucht als die Verwendung von Shell-Built-Ins.
chx
2
Ich sehe, es ist tatsächlich wichtig, ob die Absicht darin besteht, viele Dateien umzubenennen. Danke für die Abklärung!
Danieldeveloper001
1

keine Gabeln:

ls | perl -lne '$suf=substr($_,6); rename $_, "XXXXX-$suf"'

Wenn Sie eine Shell-Schleife verwenden, werden die mvGabeln einmal pro Datei ausgegeben. Perls renameBefehl funktioniert nicht.

(Perls Befehl zum Umbenennen unterliegt einigen Einschränkungen, in diesem speziellen Fall gelten diese jedoch nicht.)

Wie für den renameBefehl früher gezeigt, ja , das funktioniert, aber dann haben Sie alles , was Verwirrung zwischen zwei verschiedenen Arten von Umbenennungs und so weiter. Wenn Sie die richtige haben, großartig, aber wenn nicht, funktioniert dies auch.

Wenn Sie den Befehl perl-rename nicht haben und nicht installieren können, können Sie dies einfach tun:

ls | perl -lne '$old=$_; s/(\w+)/XXXXX/; rename $old, $_'

Wie Sie sehen, wird dabei dieselbe Substitution verwendet, die in der oberen Antwort angegeben ist. Natürlich ist die Perl-Umbenennungs hat andere Schnickschnack (die obere Antwort erwähnt, -nschon, dann gibt es -0, -fund so weiter), und je mehr von ihnen müssen Sie auf diese Weise die mehr sollten Sie , dass installieren stattdessen Ihre eigenen Walz .

Sitaram
quelle
Die üblichen Implementierungen einer Pipe haben Gabeln.
muru
Ich meinte, "werde nicht einmal pro umzubenennende Datei", im Gegensatz zu Shell, wo das "mv" / usr / bin / mv oder was auch immer gabelt. Dies liegt daran, dass der Befehl "rename" ein interner Perl-Befehl ist, der direkt rename () in libc aufruft. Natürlich gibt es einige Einschränkungen, aber in diesem speziellen Beispiel gelten diese Einschränkungen nicht.
Sitaram
1
Dies gilt auch für den renameBefehl ( Top-Antwort , verwendet auch Perl). Vielleicht sollten Sie der Antwort eine etwas ausführlichere Erklärung hinzufügen, als nur "no forks".
muru