it-swarm.com.de

Ruft nur den Dateinamen eines Pfads in einem Bash-Skript ab

Wie würde ich nur den Dateinamen ohne die Erweiterung und ohne Pfad bekommen?

Folgendes gibt mir keine Erweiterung, aber ich habe noch den Pfad angehängt:

source_file_filename_no_ext=${source_file%.*}
330
Keith

Die meisten UNIX-ähnlichen Betriebssysteme haben eine basename -Datei für einen sehr ähnlichen Zweck (und dirname für den Pfad):

pax> a=/tmp/file.txt
pax> b=$(basename $a)
pax> echo $b
file.txt

Das gibt dir leider nur den Dateinamen, einschließlich die Erweiterung, also musst du auch einen Weg finden, das zu entfernen.

Wenn Sie dies trotzdem tun müssen, können Sie auch eine Methode finden, mit der der Pfad entfernt werden kann nd die Erweiterung.

Eine Möglichkeit, dies zu tun (und dies ist eine bash- einzige Lösung, die keine anderen ausführbaren Dateien benötigt):

pax> a=/tmp/xx/file.tar.gz
pax> xpath=${a%/*} 
pax> xbase=${a##*/}
pax> xfext=${xbase##*.}
pax> xpref=${xbase%.*}
pax> echo;echo path=${xpath};echo pref=${xpref};echo ext=${xfext}

path=/tmp/xx
pref=file.tar
ext=gz

Dieses kleine Snippet setzt xpath (den Dateipfad), xpref (das Dateipräfix, nach dem Sie speziell gefragt haben) und xfext (die Dateierweiterung).

605
paxdiablo

basename und dirname Lösungen sind praktischer. Das sind alternative Befehle:

FILE_PATH="/opt/datastores/sda2/test.old.img"
echo "$FILE_PATH" | sed "s/.*\///"

Dies gibt test.old.img wie basename zurück.

Dies ist Salt-Dateiname ohne Erweiterung:

echo "$FILE_PATH" | sed -r "s/.+\/(.+)\..+/\1/"

Es gibt test.old zurück.

Die folgende Anweisung gibt den vollständigen Pfad wie der Befehl dirname an.

echo "$FILE_PATH" | sed -r "s/(.+)\/.+/\1/"

Es gibt /opt/datastores/sda2 zurück

44
Fırat KÜÇÜK

Hier ist eine einfache Möglichkeit, den Dateinamen von einem Pfad abzurufen:

echo "$PATH" | rev | cut -d"/" -f1 | rev

Um die Erweiterung zu entfernen, die Sie verwenden können, gehen Sie davon aus, dass der Dateiname nur EINEN Punkt enthält (den Erweiterungspunkt):

cut -d"." -f1
23
Ivry345
$ source_file_filename_no_ext=${source_file%.*}
$ echo ${source_file_filename_no_ext##*/}
12
ghostdog74
$ file=${$(basename $file_path)%.*}
12
mihai

Einige weitere alternative Optionen, da Regexes (regi?) Fantastisch sind!

Hier ist eine einfache Regex, um die Arbeit zu erledigen:

 regex="[^/]*$"

Beispiel (grep):

 FP="/hello/world/my/file/path/hello_my_filename.log"
 echo $FP | grep -oP "$regex"
 #Or using standard input
 grep -oP "$regex" <<< $FP

Beispiel (awk):

 echo $FP | awk '{match($1, "$regex",a)}END{print a[0]}
 #Or using stardard input
 awk '{match($1, "$regex",a)}END{print a[0]} <<< $FP

Wenn Sie einen komplizierteren regulären Ausdruck benötigen: Zum Beispiel wird Ihr Pfad in eine Zeichenfolge eingeschlossen.

 StrFP="my string is awesome file: /hello/world/my/file/path/hello_my_filename.log sweet path bro."

 #this regex matches a string not containing / and ends with a period 
 #then at least one Word character 
 #so its useful if you have an extension

 regex="[^/]*\.\w{1,}"

 #usage
 grep -oP "$regex" <<< $StrFP

 #alternatively you can get a little more complicated and use lookarounds
 #this regex matches a part of a string that starts with /  that does not contain a / 
 ##then uses the lazy operator ? to match any character at any amount (as little as possible hence the lazy)
 ##that is followed by a space
 ##this allows use to match just a file name in a string with a file path if it has an exntension or not
 ##also if the path doesnt have file it will match the last directory in the file path 
 ##however this will break if the file path has a space in it.

 regex="(?<=/)[^/]*?(?=\s)"

 #to fix the above problem you can use sed to remove spaces from the file path only
 ## as a side note unfortunately sed has limited regex capibility and it must be written out in long hand.
 NewStrFP=$(echo $StrFP | sed 's:\(/[a-z]*\)\( \)\([a-z]*/\):\1\3:g')
 grep -oP "$regex" <<< $NewStrFP

Gesamtlösung mit Regexen:

Mit dieser Funktion können Sie den Dateinamen mit oder ohne Erweiterung eines Linux-Dateipfads angeben, auch wenn der Dateiname mehrere "." Enthält. Es kann auch Leerzeichen im Dateipfad verarbeiten und wenn der Dateipfad in eine Zeichenfolge eingebettet oder eingeschlossen ist.

#you may notice that the sed replace has gotten really crazy looking
#I just added all of the allowed characters in a linux file path
function Get-FileName(){
    local FileString="$1"
    local NoExtension="$2"
    local FileString=$(echo $FileString | sed 's:\(/[a-zA-Z0-9\<\>\|\\\:\)\(\&\;\,\?\*]*\)\( \)\([a-zA-Z0-9\<\>\|\\\:\)\(\&\;\,\?\*]*/\):\1\3:g')

    local regex="(?<=/)[^/]*?(?=\s)"

    local FileName=$(echo $FileString | grep -oP "$regex")

    if [[ "$NoExtension" != "" ]]; then
        sed 's:\.[^\.]*$::g' <<< $FileName
    else
        echo "$FileName"
    fi
}

## call the function with extension
Get-FileName "my string is awesome file: /hel lo/world/my/file test/path/hello_my_filename.log sweet path bro."

##call function without extension
Get-FileName "my string is awesome file: /hel lo/world/my/file test/path/hello_my_filename.log sweet path bro." "1"

Wenn Sie sich mit einem Windows-Pfad anlegen müssen, können Sie mit diesem beginnen:

 [^\\]*$       
8
jkdba