506 Stimmen

Wie entferne ich das Dateisuffix und den Pfadteil aus einer Pfadzeichenkette in der Bash?

Bei einem String-Dateipfad wie /foo/fizzbuzz.bar wie würde ich die Bash verwenden, um nur die fizzbuzz Teil der besagten Zeichenkette?

14voto

Vinko Vrsalovic Punkte 252104

Reiner Bash-Weg:

~$ x="/foo/bar/fizzbuzz.bar.quux.zoom"; 
~$ y=${x/\/*\//}; 
~$ echo ${y/.*/}; 
fizzbuzz

Diese Funktionalität wird in man bash unter "Parameter Expansion" erklärt. Es gibt auch andere Möglichkeiten als Bash: awk, perl, sed und so weiter.

EDIT: Funktioniert mit Punkten in der Datei Suffixe und braucht das Suffix (die Erweiterung) nicht zu kennen, aber nicht Arbeit mit Punkten in der Name selbst.

7voto

Andrew Edgecombe Punkte 37795

Verwendung von basename setzt voraus, dass Sie wissen, wie die Dateierweiterung lautet, nicht wahr?

Und ich glaube, dass die verschiedenen Vorschläge für reguläre Ausdrücke nicht mit einem Dateinamen zurechtkommen, der mehr als ein ".

Das Folgende scheint mit doppelten Punkten zurechtzukommen. Oh, und Dateinamen, die selbst ein "/" enthalten (nur so zum Spaß)

Um es mit den Worten Pascals zu sagen: "Tut mir leid, dass das Drehbuch so lang ist. Ich hatte keine Zeit, es kürzer zu machen.

  #!/usr/bin/perl
  $fullname = $ARGV[0];
  ($path,$name) = $fullname =~ /^(.*[^\\]\/)*(.*)$/;
  ($basename,$extension) = $name =~ /^(.*)(\.[^.]*)$/;
  print $basename . "\n";

5voto

Benjamin W. Punkte 37771

Zusätzlich zu den POSIX-konforme Syntax verwendet in diese Antwort ,

basename string [suffix]

wie in

basename /foo/fizzbuzz.bar .bar

GNU basename unterstützt eine andere Syntax:

basename -s .bar /foo/fizzbuzz.bar

mit demselben Ergebnis. Der Unterschied und Vorteil ist, dass -s impliziert -a , die mehrere Argumente unterstützt:

$ basename -s .bar /foo/fizzbuzz.bar /baz/foobar.bar
fizzbuzz
foobar

Dies kann sogar dateinamensicher gemacht werden, indem man die Ausgabe mit NUL-Bytes trennt und die -z zum Beispiel für diese Dateien, die Leerzeichen, Zeilenumbrüche und globale Zeichen enthalten (in Anführungszeichen ls ):

$ ls has*
'has'$'\n''newline.bar'  'has space.bar'  'has*.bar'

Einlesen in ein Array:

$ readarray -d $'\0' arr < <(basename -zs .bar has*)
$ declare -p arr
declare -a arr=([0]=$'has\nnewline' [1]="has space" [2]="has*")

readarray -d erfordert Bash 4.4 oder eine neuere Version. Für ältere Versionen müssen wir eine Schleife machen:

while IFS= read -r -d '' fname; do arr+=("$fname"); done < <(basename -zs .bar has*)

3voto

mopoke Punkte 10307
perl -pe 's/\..*$//;s{^.*/}{}'

3voto

nymacro Punkte 67

Wenn Sie basename nicht verwenden können, wie in anderen Beiträgen vorgeschlagen, können Sie immer sed verwenden. Hier ist ein (hässliches) Beispiel. Es ist nicht das beste, aber es funktioniert, indem es die gewünschte Zeichenfolge extrahiert und die Eingabe durch die gewünschte Zeichenfolge ersetzt.

echo '/foo/fizzbuzz.bar' | sed 's|.*\/\([^\.]*\)\(\..*\)$|\1|g'

Damit erhalten Sie die Ausgabe

fizzbuzz

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X