如何只获取文件名而不包括扩展名和路径?
以下代码可以返回没有扩展名的文件名,但仍保留了路径:
source_file_filename_no_ext=${source_file%.*}
许多类UNIX操作系统都有一个basename
可执行文件,用于非常类似的目的(以及路径的dirname
):
pax> full_name=/tmp/file.txt
pax> base_name=$(basename ${full_name})
pax> echo ${base_name}
file.txt
不幸的是,这只会给你文件名,包括扩展名,所以你需要找到一种方法来去掉它。
因此,既然你必须这样做,你可以找到一种可以剥离路径和扩展名的方法。
其中一种方法(这是一个仅限于bash
的解决方案,不需要其他可执行文件):
pax> full_name=/tmp/xx/file.tar.gz
pax> xpath=${full_name%/*}
pax> xbase=${full_name##*/}
pax> xfext=${xbase##*.}
pax> xpref=${xbase%.*}
pax> echo "path='${xpath}', pref='${xpref}', ext='${xfext}'"
path='/tmp/xx', pref='file.tar', ext='gz'
这段小代码设置了xpath
(文件路径),xpref
(文件前缀,你特别提出的内容)和xfext
(文件扩展名)。
path=$(dirname $filename)
;并没有一个专门提供扩展名的命令,但是@paxdiablo向您展示了shell如何实现。 - Jonathan Lefflerbasname
)的方法,捕获其输出,并在bash
命令中使用该输出,就像您明确输入一样。它类似于使用反引号,但更容易嵌套必要的内容。 - paxdiablobasename
和dirname
命令更方便。这些是替代命令:
basename
和dirname
解决方案更加方便。这些是替代命令:
FILE_PATH="/opt/datastores/sda2/test.old.img"
echo "$FILE_PATH" | sed "s/.*\///"
这将返回类似于 basename
的 test.old.img
。
这是没有扩展名的salt文件名:
echo "$FILE_PATH" | sed -r "s/.+\/(.+)\..+/\1/"
它返回test.old
。
以下语句提供类似于dirname
命令的完整路径。
echo "$FILE_PATH" | sed -r "s/(.+)\/.+/\1/"
它返回/opt/datastores/sda2
file.txt
,那么这是行不通的。你的第二段代码应该是sed -r "s/(.+\/)?(.+)\..+/\2/
。 - CardinFILE_PATH="file.txt"; echo "$FILE_PATH" | sed "s/.*\///"; echo "$FILE_PATH" | sed -r "s/.+\/(.+)\..+/\1/"; echo "$FILE_PATH" | sed -r "s/(.+)\/.+/\1/"
返回3次 file.txt
。 - Fırat Küçük这里有一种从路径中获取文件名的简单方法:
echo "$PATH" | rev | cut -d"/" -f1 | rev
如果文件名仅有一个点(即扩展名点),您可以使用以下方法删除扩展名:
cut -d"." -f1
PATH
,因为这可能会与系统的PATH
变量发生冲突。 - TabeaKischka$ file=${$(basename $file_path)%.*}
echo $(basename $the_file_path) | sed "s/\..*//"
,将其翻译为“将文件路径中的文件名提取出来,并通过sed命令去掉文件名中最后一个点及其后面的内容。” - Marshal因为正则表达式很棒,所以这里提供一些更多的替代选项!
这里有一个简单的正则表达式可以完成工作:
regex="[^/]*$"
例子(grep):
FP="/hello/world/my/file/path/hello_my_filename.log"
echo $FP | grep -oP "$regex"
#Or using standard input
grep -oP "$regex" <<< $FP
示例(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
如果您需要更复杂的正则表达式:例如,您的路径被包裹在一个字符串中。
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
使用正则表达式的完整解决方案:
即使文件名中有多个“.”,此函数可以提供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"
如果你必须要处理一个Windows路径,你可以从这个开始:
[^\\]*$
$ source_file_filename_no_ext=${source_file%.*}
$ echo ${source_file_filename_no_ext##*/}
filename="${fileNameWithPath##*/}"
- Alex Hall
echo $(basename "${filepath%.*}")
- signal