Wie entferne ich das Dateisuffix und den Pfadteil von einer Pfadzeichenfolge in Bash?

Wenn ich einen String-Dateipfad wie “/foo/fizzbuzz.bar” verwende, wie würde ich bash verwenden, um nur den “fizzbuzz” -Teil der Saite zu extrahieren?

Hier erfahren Sie, wie Sie es mit den Operatoren # und% in Bash machen.

$ x="/foo/fizzbuzz.bar" $ y=${x%.bar} $ echo ${y##*/} fizzbuzz 

${x%.bar} könnte auch ${x%.*} , um alles nach einem Punkt oder ${x%%.*} zu entfernen, um alles nach dem ersten Punkt zu entfernen.

Beispiel:

 $ x="/foo/fizzbuzz.bar.quux" $ y=${x%.*} $ echo $y /foo/fizzbuzz.bar $ y=${x%%.*} $ echo $y /foo/fizzbuzz 

Dokumentation kann im Bash Handbuch gefunden werden . Suchen Sie nach dem passenden Abschnitt für den Abschnitt ${parameter%word} und ${parameter%%word} .

Sehen Sie sich den Befehl basename an:

 NAME=`basename /foo/fizzbuzz.bar .bar` 

Pure Bash, in zwei getrennten Operationen:

  1. Entfernen Sie den Pfad von einer Pfadzeichenfolge:

     path=/foo/bar/bim/baz/file.gif file=${path##*/} #$file is now 'file.gif' 
  2. Entfernen Sie die Erweiterung aus einer Pfadzeichenfolge:

     base=${file%.*} #${base} is now 'file'. 

Mit basename habe ich folgendes erreicht:

 for file in *; do ext=${file##*.} fname=`basename $file $ext` # Do things with $fname done; 

Dies erfordert keine a priori Kenntnis der Dateierweiterung und funktioniert auch, wenn Sie einen Dateinamen haben, der Punkte in seinem Dateinamen hat (vor seiner Erweiterung); es erfordert jedoch das Programm basename , aber dies ist Teil der GNU coreutils, daher sollte es mit jeder Distribution ausgeliefert werden.

Reiner Bash-Weg:

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

Diese functionalität wird unter bash unter “Parametererweiterung” erklärt. Non Bash Wege im Überfluss: awk, perl, sed und so weiter.

BEARBEITEN: Arbeitet mit Punkten in Dateisuffixen und muss nicht das Suffix (Erweiterung) kennen, aber arbeitet nicht mit Punkten im Namen selbst.

Die functionen basename und dirname stehen Ihnen zur Verfügung:

 mystring=/foo/fizzbuzz.bar echo basename: $(basename $mystring) echo basename + remove .bar: $(basename $mystring .bar) echo dirname: $(dirname $mystring) 

Hat ausgegeben:

 basename: fizzbuzz.bar basename + remove .bar: fizzbuzz dirname: /foo 
 perl -pe 's/\..*$//;s{^.*/}{}' 

Die Verwendung von basename geht davon aus, dass Sie wissen, was die Dateierweiterung ist, oder?

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

Das Folgende scheint mit Doppelpunkten zurecht zu kommen. Oh, und Dateinamen, die ein “/” enthalten (nur für Tritte)

Pascals Umschreibung: “Entschuldigung, dieses Skript ist so lang. Ich hatte keine Zeit, es kürzer zu machen.”

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

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

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

Welches wird dir die Ausgabe bringen

Fizzbuzz

Vorsicht vor der vorgeschlagenen Perl-Lösung: Es entfernt alles nach dem ersten Punkt.

 $ echo some.file.with.dots | perl -pe 's/\..*$//;s{^.*/}{}' some 

Wenn Sie es mit Perl machen wollen, funktioniert das:

 $ echo some.file.with.dots | perl -pe 's/(.*)\..*$/$1/;s{^.*/}{}' some.file.with 

Aber wenn Sie Bash verwenden, sind die Lösungen mit y=${x%.*} (Oder basename "$x" .ext wenn Sie die Erweiterung kennen) viel einfacher.

Kombinieren der am besten bewerteten Antwort mit der zweitobersten Antwort, um den Dateinamen ohne den vollständigen Pfad zu erhalten:

 $ x="/foo/fizzbuzz.bar.quux" $ y=(`basename ${x%%.*}`) $ echo $y fizzbuzz 

Der Basisname macht das, entfernt den Pfad. Es wird auch das Suffix entfernen, wenn es angegeben wird und wenn es mit dem Suffix der Datei übereinstimmt, aber Sie müssen das Suffix kennen, das Sie dem Befehl geben können. Ansonsten kannst du mv verwenden und herausfinden, wie der neue Name sein sollte.

Informationen finden Sie im Bash-Handbuch , suchen Sie nach ${parameter%word} und ${parameter%%word} im Abschnitt zum ${parameter%%word} Abschnitte.