首页 文章

从Bash脚本中的路径获取文件名[重复]

提问于
浏览
297

这个问题在这里已有答案:

如何在没有扩展名且没有路径的情况下获取文件名?

以下给我没有扩展,但我仍然附加路径:

source_file_filename_no_ext=${source_file%.*}

6 回答

  • 7

    大多数类UNIX操作系统都有一个 basename 可执行文件用于非常类似的目的(并且路径为 dirname ):

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

    不幸的是,它只是为您提供了文件名,包括扩展名,因此您需要找到一种方法来删除它 .

    所以,无论如何你必须这样做,你也可以找到一种方法来剥离路径和扩展 .

    一种方法(这是一个 bash -only解决方案,不需要其他可执行文件):

    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
    

    那个小片段设置 xpath (文件路径), xpref (文件前缀,你特别要求的)和 xfext (文件扩展名) .

  • 11

    basenamedirname 解决方案更方便 . 这些是替代命令:

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

    这将返回 test.old.img ,如 basename .

    这是没有扩展名的salt文件名:

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

    它返回 test.old .

    以下语句给出了完整的路径,如 dirname 命令 .

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

    它返回 /opt/datastores/sda2

  • 536

    这是从路径获取文件名的简单方法:

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

    要删除您可以使用的扩展名,假设文件名只有一个点(扩展点):

    cut -d"." -f1
    
  • 31
    $ source_file_filename_no_ext=${source_file%.*}
    $ echo ${source_file_filename_no_ext##*/}
    
  • 8
    $ file=${$(basename $file_path)%.*}
    
  • 21

    还有一些替代选项,因为正则表达式(regi?)非常棒!

    Here is a Simple regex to do the job:

    regex="[^/]*$"
    

    Example (grep):

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

    Example (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
    

    If you need a more complicated regex: 例如,您的路径包含在字符串中 .

    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
    

    Total solution with Regexes:

    即使文件名中包含多个“ . ”,此函数也可以为您提供带或不带linux文件路径扩展名的文件名 . 它还可以处理文件路径中的空格,以及文件路径是嵌入还是包装在字符串中 .

    #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"
    

    If you have to mess with a windows path you can start with this one:

    [^\\]*$
    

相关问题