Ich verwende dies in einem Kundenverzeichnis, um Dateien umzubenennen, wobei der erste Buchstabe jedes Wortes gemäß seiner Anfrage großgeschrieben wird:
rename 's/\b(\w)/\u$1/g' *
Das funktioniert gut, aber es wird auch der erste Buchstabe der Erweiterung großgeschrieben. Ich verwende dies, um Folgendes zu beheben:
rename 's/\.Txt$/.txt/' *.Txt
Das funktioniert in Ordnung, wenn die meisten Dateien in einem Ordner dieselbe Erweiterung haben (im Allgemeinen wahr), ist aber ein Schmerz, wenn sie sehr gemischt sind.
Um dieses Problem zu umgehen, habe ich ein kleines Skript erstellt, das so aussieht (nicht lachen!):
#!/bin/bash
rename 's/\.Txt$/.txt/' *.Txt
rename 's/\.Doc$/.doc/' *.Doc
rename 's/\.Docx$/.docx/' *.Docx
...
rename 's/\.Xlsx$/.xlsx/' *.Xlsx
Ich ignoriere die Fehler 'Kann * .Txt * .txt nicht umbenennen: Keine solche Datei oder kein solches Verzeichnis' und wenn ich eine fehlende Erweiterung finde, füge ich diese Zeile einfach meinem Skript hinzu.
Ich denke nicht, dass dies von Bedeutung sein wird, aber die Dateien befinden sich auf einem Windows-Server-Fileshare, aber ich greife mit Ubuntu 16.04LTS darauf zu. Wenn es wichtig ist, kann ich sie zuerst auf mein lokales Laufwerk kopieren, einen Befehl in Ubuntu ausführen und die Dateien bei Bedarf zurück verschieben.
Gibt es eine Möglichkeit, den ersten Umbenennungsbefehl zu ändern, um die Erweiterungen zu ignorieren und als Kleinbuchstaben zu belassen? Kann ich den neuen Befehl in einem übergeordneten Verzeichnis ausführen und ihn durch alle Unterverzeichnisse rekursieren lassen?
filename.txt
werdenFilename.txt
, richtig? Kannst du ein Beispiel geben ?Antworten:
Eine Möglichkeit, dies zu erreichen, könnte darin bestehen, Negative Lookbehind zu verwenden, um nur mit der Wortgrenze - Wortzeichenfolge übereinzustimmen , wenn ihr keine wörtliche Periode vorausgeht, z
dann
Angenommen, Sie möchten auch vermeiden, die Pluralisierung zu aktivieren
s
, können wir dies ändernoder auch
quelle
rename -n 's/(?<![.'\''])\b\w*/\u$&/g' *
Vielen Dank für Ihre Hilfe!-n
tatsächlich umzubenennen.Dadurch wird der erste Buchstabe jedes Wortes mit Ausnahme der letzten Erweiterung groß geschrieben:
Ich habe mit diesen Dateien getestet:
Und es wird sie umbenennen als:
Der Trick besteht darin, zuerst jeden ersten Buchstaben groß zu schreiben, die Erweiterungen zu ignorieren und dann zurück zu gehen und die Erweiterung in Kleinbuchstaben zu schreiben:
s/\b(.+?)\b/\u$1/g;
: Das.+?
ist ein nicht gieriges Muster, was bedeutet, dass es die kürzestmögliche Übereinstimmung findet. Da es durch Wortgrenzen (\b
) verankert ist , werden alle Wörter gefunden (alle wegen des Finalesg
). Diese werden dann durch die großgeschriebene Version von sich selbst (\l$1
) ersetzt.s/(.+)\.(.)/$1\.\l$2/
: das.+
ist gierig, so wird es die längstmögliche Übereinstimmung finden. Dies bedeutet die längste Zeichenfolge bis zum Ende.
, danach die Erweiterung (falls vorhanden). Wir ersetzen die Übereinstimmung durch alles vor der Erweiterung ($1
), a.
und die Erweiterung durch den ersten Buchstaben, der wieder in Großbuchstaben geschrieben wird (\l$2
).Rekursion ist auch einfach genug. Wenn Ihre Shell bash ist (wenn Sie es nicht wissen, ist es wahrscheinlich), können Sie die Globstar-Option verwenden, mit der
**
0 oder mehr Unterverzeichnisse übereinstimmen:Führen Sie nun den Befehl zum Umbenennen wie folgt aus (dies funktioniert auch für alle Dateien in Ihrem aktuellen Verzeichnis):
Verwenden Sie
**/*.*
anstelle von nur Dateien oder Verzeichnisse mit Erweiterungen**
.Alternativ können Sie Folgendes verwenden
find
:Und um auf diese Dateien und Verzeichnisse mit einer Erweiterung zu beschränken:
Beachten Sie, dass alle diese Lösungen sowohl Verzeichnisse als auch Dateien fröhlich umbenennen . Wenn Sie das nicht wollen, achten Sie darauf, wo Sie es wiederholen sollen, oder geben Sie ihm ein spezifischeres Muster wie
*.txt
.Entfernen Sie in allen Beispielen das -n, damit sie tatsächlich etwas tun. Die
-n
Ursachenrename
, einfach zu drucken, was es tun würde und eigentlich nichts zu tun. Nützlich zum Testen.quelle
rename -n 's/\b(.+?)\b/\u$1/g; s/(.+)\.(.)/$1\.\l$2/' *
und es funktioniert fast, aber es nutzt auch die Possessiven vonAlan's
. Sieht so aus, als hätte SteelDriver unten eine Antwort mitrename -n 's/(?<![.'\''])\b\w*/\u$&/g' *
Vielen Dank für Ihre Hilfe!Am sinnvollsten wäre es, alle "Wörter" (unter Verwendung der Wortgrenze
\b
und unter Bezugnahme$1
auf ein erstes Zeichen) einschließlich der Erweiterung anzugehen , dann aber die Erweiterung selbst in Kleinbuchstaben zu schreiben:Beachten Sie, dass dies für Dateinamen mit Unterstrichen nicht funktioniert, dh "Wort" -Grenzen werden bei Leerzeichen berücksichtigt (Tabulatoren, Leerzeichen, Zeilenumbrüche - die hoffentlich sowieso nicht im Dateinamen enthalten sein sollten).
Beachten Sie die Verwendung von
prename
für die Portabilität aufksh
, wobeirename
es sich tatsächlich um einen integrierten Befehl handelt, nicht um die eigenständigeperl
ausführbare Datei.quelle
alan's file.txt
alsAlan's file.txt
(das zweite Wort wird nicht groß geschrieben).rename files with first letter of each word being capitalised
ist das okay? In Bezug auf das Array könnte ich tun*.*
?*.*
wäre in Ordnung, wenn es nur einen.
im Dateinamen geben würde, dh neinfoo.bar.txt
. Danke für die Bearbeitung, übrigens, ich werde jetzt daran arbeiten, meine Antwort zu bearbeiten*.*
sollte alle nicht versteckten Dateien mit einer Erweiterung abgleichen , einschließlichfoo.bar.txt
,*.*
sollte also gut funktionieren. Sie müssen keine Liste mit Erweiterungen angeben.Verwenden Sie einfach
rename 's/\b(\w)/\u$1/' *
OHNE das g-Flag.Das g-Flag bedeutet "global = mehrmals ausführen". Sie machen das erste Mal im Dateinamen und möchten das zweite Mal nicht in Großbuchstaben schreiben, oder?
quelle
zz alan.txt
umbenannt wurde,Alan's file.txt
was nicht sehr wahrscheinlich ist :)rename 's/(.*)\.(\w)(.*)/$1.\l$2$3/' *
Dies macht das Wort vor dem letzten Punkt klein. Also vonQwe.Asd.Zxc
bisQwe.Asd.zxc
`