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

本文翻译自:Get just the filename from a path in a Bash script [duplicate]

This question already has an answer here: 这个问题已经在这里有了答案:

How would I get just the filename without the extension and no path? 我如何只获取没有扩展名和路径的文件名?

The following gives me no extension, but I still have the path attached: 下面没有给我扩展名,但是我仍然附加了路径:

source_file_filename_no_ext=${source_file%.*}

#1楼

参考:https://stackoom.com/question/E6qe/从Bash脚本中的路径中获取文件名-重复


#2楼

Here is an easy way to get the file name from a path: 这是从路径获取文件名的简单方法:

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

To remove the extension you can use, assuming the file name has only ONE dot (the extension dot): 要删除扩展名,可以使用,假设文件名只有一个点(扩展名点):

cut -d"." -f1

#3楼

basename and dirname solutions are more convenient. basenamedirname解决方案更加方便。 Those are alternative commands: 这些是替代命令:

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

This returns test.old.img like basename . 这将返回test.old.imgbasename

This is salt filename without extension: 这是不带扩展名的盐文件名:

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

It returns test.old . 它返回test.old

And following statement gives the full path like dirname command. 以下语句给出了完整的路径,如dirname命令。

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

It returns /opt/datastores/sda2 它返回/opt/datastores/sda2


#4楼

Most UNIX-like operating systems have a basename executable for a very similar purpose (and dirname for the path): 大多数类似UNIX的操作系统都有一个基basename可执行文件,其用途非常相似(路径的dirname也是如此):

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

That unfortunately just gives you the file name, including the extension, so you'd need to find a way to strip that off as well. 不幸的是,该文件名仅包含文件名( 包括扩展名),因此您还需要找到一种剥离文件名的方法。

So, given you have to do that anyway, you may as well find a method that can strip off the path and the extension. 因此,无论如何您都必须这样做,您也可能会找到一种可以去除路径扩展名的方法。

One way to do that (and this is a bash -only solution, needing no other executables): 一种方法(这是仅使用bash解决方案,不需要其他可执行文件):

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

That little snippet sets xpath (the file path), xpref (the file prefix, what you were specifically asking for) and xfext (the file extension). 这个小片段设置了xpath (文件路径), xpref (文件前缀,您具体要求的内容)和xfext (文件扩展名)。


#5楼

$ source_file_filename_no_ext=${source_file%.*}
$ echo ${source_file_filename_no_ext##*/}

#6楼

Some more alternative options because regexes (regi ?) are awesome! 一些其他替代选项,因为正则表达式(regi?)很棒!

Here is a Simple regex to do the job: 这是完成此工作的简单正则表达式:

 regex="[^/]*$"

Example (grep): 范例(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): 示例(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: For example your path is wrapped in a string. 如果您需要更复杂的正则表达式:例如,您的路径包含在字符串中。

 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: 正则表达式的整体解决方案:

This function can give you the filename with or without extension of a linux filepath even if the filename has multiple "."s in it. 即使文件名中包含多个“。”,此函数也可以为您提供带或不带linux文件路径扩展名的文件名。 It can also handle spaces in the filepath and if the file path is embedded or wrapped in a string. 它还可以处理文件路径中的空格以及文件路径是嵌入还是包装在字符串中。

#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: 如果您必须弄乱Windows路径,则可以从以下路径开始:

 [^\\]*$       
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值