Sie brauchen sich nicht mit awk
o sed
oder sogar perl
für diese einfache Aufgabe. Es gibt eine reine Bash, os.path.splitext()
-kompatible Lösung, die nur Parametererweiterungen verwendet.
Referenz Implementierung
Dokumentation von os.path.splitext(path)
:
Den Pfadnamen Pfad in ein Paar aufteilen (root, ext)
tal que root + ext == path
y ext leer ist oder mit einem Punkt beginnt und höchstens einen Punkt enthält. Führende Punkte im Basisnamen werden ignoriert; splitext('.cshrc')
gibt zurück. ('.cshrc', '')
.
Python-Code:
root, ext = os.path.splitext(path)
Bash-Implementierung
Ehrung von Spitzenzeiten
root="${path%.*}"
ext="${path#"$root"}"
Führende Perioden ignorieren
root="${path#.}";root="${path%"$root"}${root%.*}"
ext="${path#"$root"}"
Tests
Hier sind Testfälle für die Führende Perioden ignorieren Implementierung, die bei jeder Eingabe mit der Python-Referenzimplementierung übereinstimmen sollte.
|---------------|-----------|-------|
|path |root |ext |
|---------------|-----------|-------|
|' .txt' |' ' |'.txt' |
|' .txt.txt' |' .txt' |'.txt' |
|' txt' |' txt' |'' |
|'*.txt.txt' |'*.txt' |'.txt' |
|'.cshrc' |'.cshrc' |'' |
|'.txt' |'.txt' |'' |
|'?.txt.txt' |'?.txt' |'.txt' |
|'\n.txt.txt' |'\n.txt' |'.txt' |
|'\t.txt.txt' |'\t.txt' |'.txt' |
|'a b.txt.txt' |'a b.txt' |'.txt' |
|'a*b.txt.txt' |'a*b.txt' |'.txt' |
|'a?b.txt.txt' |'a?b.txt' |'.txt' |
|'a\nb.txt.txt' |'a\nb.txt' |'.txt' |
|'a\tb.txt.txt' |'a\tb.txt' |'.txt' |
|'txt' |'txt' |'' |
|'txt.pdf' |'txt' |'.pdf' |
|'txt.tar.gz' |'txt.tar' |'.gz' |
|'txt.txt' |'txt' |'.txt' |
|---------------|-----------|-------|
Test Ergebnisse
Alle Tests wurden bestanden.
0 Stimmen
Diese Frage erklärt diese Bash-Technik und einige andere verwandte Techniken.
44 Stimmen
Wenn Sie die großartigen Antworten unten anwenden, fügen Sie nicht einfach Ihre Variable ein, wie ich es hier zeige Falsch:
extension="{$filename##*.}"
wie ich es eine Zeit lang getan habe! Bewegen Sie die$
außerhalb der Curlys: Richtig:extension="${filename##*.}"
4 Stimmen
Dies ist eindeutig ein nicht triviales Problem, und für mich ist es schwer zu sagen, ob die nachstehenden Antworten völlig korrekt sind. Es ist erstaunlich, dass dies kein eingebauter Vorgang in (ba)sh ist (die Antworten scheinen die Funktion mittels Mustervergleich zu implementieren). Ich beschloss, Pythons
os.path.splitext
stattdessen wie oben...1 Stimmen
Als Erweiterung vertreten müssen Natur einer Datei, gibt es eine Magie Befehl, der die Datei prüft, um sein Wesen zu erraten und zu offerieren Standarderweiterung . siehe meine Antwort
8 Stimmen
Die Frage ist von vornherein problematisch, weil Aus der Sicht des Betriebssystems und der Unix-Dateisysteme im Allgemeinen gibt es so etwas wie eine Dateierweiterung nicht. Die Verwendung eines "." zur Trennung von Teilen ist eine menschliche Konvention Das funktioniert nur so lange, wie die Menschen bereit sind, sich daran zu halten. Bei dem Programm "tar" könnte zum Beispiel beschlossen worden sein, Ausgabedateien mit einem "tar."-Präfix anstelle eines ".tar"-Suffixes zu benennen - also "tar.somedir" anstelle von "somedir.tar". Aus diesem Grund gibt es keine "allgemeine, immer funktionierende" Lösung - Sie müssen Code schreiben, der Ihren spezifischen Bedürfnissen und erwarteten Dateinamen entspricht.
0 Stimmen
@C. M.s Kommentar ist die beste Antwort! In meinem Fall hatten alle Dateien das gleiche Präfix (input.*) und ich wollte nur die Erweiterung, um das Präfix ändern zu können (z. B. umbenennen, aber das hatte ich nicht zur Verfügung). Also habe ich dies getan:
for f in input.*; do ext=$(echo $f | cut -c 7-); mv $f "output.$ext"; done
0 Stimmen
@PeterGibson schlechter Ansatz... jetzt haben Sie eine Python-Instanz geöffnet und den Musterabgleich darin verwendet, anstatt nur den Musterabgleich in der Shell zu verwenden @C.M. so etwas wie "keine Dateierweiterung" gibt es nicht. jeder weiß, was eine Dateierweiterung ist und ist bereits von allen anerkannt. der einzige Unterschied in *nix-Systemen ist, dass der Typ einer Datei durch den Shebang angegeben wird
#!
innerhalb der Datei, wenn sie existiert. Andernfalls wird sie durch die Erweiterung der Datei angegeben, wenn sie existiert. Wenn keine der beiden vorhanden ist, wird sie standardmäßigapplication/octet-stream
mime type.1 Stimmen
Wie lautet die Erweiterung der Datei
xyzzy.tar.gz
? Oderplugh.cfg.saved
? Mit anderen Worten: Behandeln Sie die Erweiterung als eine einfache technische Frage oder als eine semantische Frage?