Was ist ein guter Befehl, um Leerzeichen, Bindestriche und Unterstriche aus allen Dateien in einem Verzeichnis oder ausgewählten Dateien zu löschen?
Ich verwende den folgenden Befehl mit benutzerdefinierten Thunar-Aktionen, um Dateinamen zu löschen:
for file in %N; do mv "$file" "$(echo "$file" | tr -s ' ' | tr ' A-Z' '-a-z' | tr -s '-' | tr -c '[:alnum:][:cntrl:].' '-')"; done
Dieser Befehl ersetzt jedoch nur Leerzeichen durch Bindestriche / Bindestriche und Kleinbuchstaben.
Ich habe den folgenden Befehl im Terminal verwendet, um Leerzeichen aus Tausenden von Dateinamen in einem Ordner zu löschen, und es hat ziemlich schnell funktioniert:
rename "s/ //g" *
Auch hier werden nur Leerzeichen gelöscht und keine Bindestriche / Bindestriche und Unterstriche.
Im Idealfall möchte ich keine Leerzeichen, Bindestriche / Bindestriche und Unterstriche in meinen Dateinamen. Und es wäre großartig, wenn der Befehl mit benutzerdefinierten Thunar-Aktionen für ausgewählte Dateien verwendet werden könnte.
quelle
rename -i "s/[-_ ]//g" *
echo $file | sed -e 's/[ _-]//g'
; erledigtAntworten:
Die
rename
mit demperl
Paket gelieferte Version unterstützt reguläre Ausdrücke:Alternative,
Das
-i
Flagrename
verwendet den interaktiven Modus und fragt, ob das Ziel bereits vorhanden ist, anstatt es stillschweigend zu überschreiben.Perls Umbenennung wird manchmal genannt
prename
.Perls Umbenennung versus Umbenennung von util-linux
Auf Debian-ähnlichen Systemen scheint die Umbenennung von Perl die Standardeinstellung zu sein, und die oben genannten Befehle sollten einfach funktionieren.
Bei einigen Distributionen ist das
rename
Dienstprogramm von util-linux die Standardeinstellung. Dieses Dienstprogramm ist vollständig nicht mit Perl kompatibelrename
.Alle: Überprüfen Sie zunächst, ob Perls
rename
unter dem Namen verfügbar istprename
.Debian: Perls Umbenennung sollte die Standardeinstellung sein. Es ist auch als erhältlich
prename
. Dierename
ausführbare Datei steht jedoch unter der Kontrolle von/etc/alternatives
und könnte daher in etwas anderes geändert worden sein.archlinux: Ausführen
pacman -S perl-rename
und der Befehl ist verfügbar alsperl-rename
. Erstellen Sie für einen bequemeren Namen einen Alias. (Hutspitze: ChiseledAbs)Mac OSX Nach dieser Antwort ,
rename
kann auf OSX installiert werden homebrew mit über:Direkter Download:
rename
ist auch bei Perl Monks erhältlich:quelle
rename
du sprichst. Der von util-linux -2.24.2-1.fc20.x86_64 unterstützt keine regulären Ausdrücke.rename
sieht die vom OP verwendeteperl
Version wie die Version und nicht wie dieutil-linux
Version aus.rename
Manpage für die Util-Linux- Version. Abgesehen von dieser Notiz ist es wichtig, dass der OP seine Antwort erhielt (und Sie eine positive Bewertung von mir :-D).pacman -S perl-rename
dann ich denke du kannst alias.Ich würde alle diese
tr
Befehle durch einensed
Ersetzungsbefehl ersetzen , z.quelle
Ohne zu zählen
mv
, brauchen Sie dafür überhaupt keinen externen Prozess - Sie können sie einfach nur bescheißen .Dies bedeutet jedoch einen
mv
Aufruf pro Datei und ist daher wahrscheinlichrename
besser. Dies sollte jedoch funktionieren, wenn nur ein POSIXmv
in$PATH
und eine POSIX-Shell vorhanden sind.Also habe ich mir dafür eine Art verrückte Demo ausgedacht. Der Testsatz wird wie folgt generiert:
Zunächst werde ich als erster anerkennen, dass der obige Befehl Ergebnisse liefert, die auf andere Weise leichter zu erhalten sind. Aber andere Mittel würden wahrscheinlich nicht so gut zeigen, was mit
$IFS
ein wenig (krank?) Fantasie getan werden könnte .Das erste Bit ist also ziemlich einfach:
tee
leitet 5 Kopien seiner Eingabe heraus - das heredocument heißtCGEN
dd
blockiert seine Eingabe durch Zeilenumbrüche mit 90 Bytes pro Block und leitet diese an ...sed
\n
Verbindet 2 dieser Blöcke mit zwei Ewline-Zeichen, setzt'
die Ergebnisse in einfache Anführungszeichen und stellt die Zeichenfolgetouch --
für jeden Zeilenzyklus voran, bevor sie an ...sh
Das führt dann alle Eingaben als Shell-Befehle ausDas
#CGEN
bisschen aber ... Nun, kurz ...Die Unterseite
printf
druckt 252 0sDer vorletzte erhält 252
''
Null-String-Argumente und druckt für jeden den Inhalt von$n
gefolgt von dem String" $i "
eval
interpretiert die Argumente des nächsten nach oben,printf
bevor die Ergebnisse dieser Interpretation als Oktalzahlen gedruckt werden, denen 2 Backslashes pro Stück vorangestellt sindDer letzte gibt
printf
die Bytewerte für diese Oktale 2 gleichzeitig aus, gefolgt von der Zeichenfolge-_ ---___
für jedes Paar$n
wird mit einer Gleichung initialisiert, die$i
bei jeder Auswertung um eins erhöht wird, mit der Ausnahme, dass die Werte 10, 39 oder 47 übersprungen werden (\n
ewline,'
einfache Anführungszeichen und/
Schrägstrich in ASCII-Dezimalzahl).Das Endergebnis ist ein Verzeichnis mit vielen wirklich hässlichen Dateinamen, die jedes Byte in meinem Zeichensatz von 1 bis 255 enthalten, mit Ausnahme des einfachen Anführungszeichens (nur übersprungen, um eine weitere
sed s///
Anweisung zu vermeiden ) und des/
Schrägstrichs. Diese Dateinamen sehen folgendermaßen aus:Jetzt werde ich einige Daten zu diesen Dateien erhalten:
AUSGABE
In Ordnung. Nun endlich zum Handeln:
AUSGABE
Erfolg! Sie können selbst sehen:
quelle
IFS
+printf
set -- 'some arbitrary' args; eval printf '"%s\n"' "$(IFS=0; printf ' "$@" %s' $(printf %025d))"
new="$(IFS=" -_"; printf %s $1)"
gabelt eine Unterschale (außer in ksh93) und hat Probleme mit dem Tailing von Zeilenumbrüchen. Eine andere Option ist zu verwendenIFS=' -_'; set -- $1; IFS=; new="$*"
(und ändern Sie Ihre while-Schleife in eine for-Schleife)[ -e x ]
gibt false zurück, wennx
es sich um einen Symlink zu einer nicht vorhandenen oder nicht zugänglichen Datei handelt.Wenn Sie Perl haben, müssen Sie normalerweise umbenennen. du kannst tun:
und zeigen Sie, wie dieses Skript geschrieben ist:
Dieses Skript unterstützt das Flag -i nicht (dies ist die Version in meinem System), aber möglicherweise unterstützt Ihr Flag. Was ist mit Argumenten? Das erste sind reguläre Ausdrücke im PCRE-Format. Sie funktionieren wie Filter. Ändern Sie den Eingabenamen in den Ausgabenamen. Liste der Eingabenamen, die Sie mit dem Sternchen '*' angeben. Zum Beispiel tun Sie:
in real '*' kann erweitert werden zu:
Wenn Sie wirklich große Dateien haben, sind Sie in der Falle. Shell wird Ihre Linie länger erweitern, als das System akzeptiert. Dann können Sie eine Problemumgehung mit find oder xargs durchführen. Die Verwendung von 'find' ist ein Problem, da das Umbenennen mehrmals aufgerufen wird, was der Anzahl der Dateien im Verzeichnis entspricht. Verwenden Sie besser xargs mit der Option -r. Ein Umbenennungsaufruf ändert viele Dateien. beispielsweise:
letztes Problem, was bedeutet es:
Dies ist ein regulärer Ausdruck zum Ändern von Namen. Nach dem ersten '/' steht das Leerzeichen. Dies wird erkannt und nach dem zweiten '/' durch einen String ersetzt. Aber es gibt eine leere Zeichenfolge, die mit dem dritten '/' endet, dann wird das Leerzeichen durch nichts ersetzt. Option 'g' wiederholt diesen Ausdruck. Der Ausdruck wird von Anfang bis Ende nach allen Namen durchsucht und erkennt alle Leerzeichen.
Aber was ist, wenn Sie ein Tabulatorzeichen oder ein anderes "weißes" Zeichen haben? Es gibt Ersatz für dieses '\ s'. Welche anderen nicht benötigten Charaktere? füge es einfach dem Ausdruck hinzu. Alle schließen mit Klammern, zum Beispiel:
das ist alles. siehst du Ähnlichkeit? Ich denke, Sie sollten man perlrequick und man perlretut lesen, dies erklärt Ihnen (ich hoffe), wie regulärer Ausdruck funktioniert. Sie können den Befehl zum Umbenennen in Ihrem eigenen Skript verwenden, wenn Sie ihn benötigen.
quelle
Die folgende
sh
Shell-Schleife entfernt alle Leerzeichen, Unterstriche und Bindestriche aus den Namen der Dateien im aktuellen Verzeichnis, wobei darauf geachtet wird, dass keine vorhandenen Dateien überschrieben werden:Für
bash
undksh
, und etwas ausführlicher mit der Logik:Entfernen Sie das,
echo
wenn Sie sicher sind, dass es das tut, was Sie wollen.Der
tr
Befehl löscht (-d
) alle Zeichen im angegebenen Zeichensatz (' _-'
). Es ist wichtig, dass der Bindestrich ganz am Anfang oder Ende des Satzes steht, da er sonst als Zeichenbereich interpretiert wird.quelle