我想分别获取文件名(不带扩展名)和扩展名。
到目前为止,我找到的最佳解决方案是:
NAME=`echo "$FILE" | cut -d'.' -f1`
EXTENSION=`echo "$FILE" | cut -d'.' -f2`
这是错误的,因为如果文件名包含多个,它就不起作用。字符。假设我有a.b.js,它会考虑a和b.js而不是a.b和js。
它可以在Python中用
file, ext = os.path.splitext(path)
但如果可能的话,我不希望仅仅为此启动Python解释器。
有更好的主意吗?
如果文件没有扩展名或文件名,这似乎不起作用。这是我正在使用的;它只使用内置文件名,并处理更多(但不是所有)病态文件名。
#!/bin/bash
for fullpath in "$@"
do
filename="${fullpath##*/}" # Strip longest match of */ from start
dir="${fullpath:0:${#fullpath} - ${#filename}}" # Substring from 0 thru pos of filename
base="${filename%.[^.]*}" # Strip shortest match of . plus at least one non-dot char from end
ext="${filename:${#base} + 1}" # Substring from len of base thru end
if [[ -z "$base" && -n "$ext" ]]; then # If we have an extension and no base, it's really the base
base=".$ext"
ext=""
fi
echo -e "$fullpath:\n\tdir = \"$dir\"\n\tbase = \"$base\"\n\text = \"$ext\""
done
下面是一些测试用例:
$ basename-and-extension.sh / /home/me/ /home/me/file /home/me/file.tar /home/me/file.tar.gz /home/me/.hidden /home/me/.hidden.tar /home/me/.. .
/:
dir = "/"
base = ""
ext = ""
/home/me/:
dir = "/home/me/"
base = ""
ext = ""
/home/me/file:
dir = "/home/me/"
base = "file"
ext = ""
/home/me/file.tar:
dir = "/home/me/"
base = "file"
ext = "tar"
/home/me/file.tar.gz:
dir = "/home/me/"
base = "file.tar"
ext = "gz"
/home/me/.hidden:
dir = "/home/me/"
base = ".hidden"
ext = ""
/home/me/.hidden.tar:
dir = "/home/me/"
base = ".hidden"
ext = "tar"
/home/me/..:
dir = "/home/me/"
base = ".."
ext = ""
.:
dir = ""
base = "."
ext = ""
您可以使用POSIX参数扩展的魔力:
bash-3.2$ FILENAME=somefile.tar.gz
bash-3.2$ echo "${FILENAME%%.*}"
somefile
bash-3.2$ echo "${FILENAME%.*}"
somefile.tar
如果您的文件名是这样的格式,则需要注意/somefile.tar.gz然后echo${FILENAME%%.*}会贪婪地删除最长的匹配项。你会得到空字符串。
(您可以使用临时变量解决此问题:
FULL_FILENAME=$FILENAME
FILENAME=${FULL_FILENAME##*/}
echo ${FILENAME%%.*}
)
本网站提供了更多信息。
${variable%pattern}
Trim the shortest match from the end
${variable##pattern}
Trim the longest match from the beginning
${variable%%pattern}
Trim the longest match from the end
${variable#pattern}
Trim the shortest match from the beginning
使用示例文件/Users/Jonathan/Scripts/bash/MyScript.sh,以下代码:
MY_EXT=".${0##*.}"
ME=$(/usr/bin/basename "${0}" "${MY_EXT}")
将导致${ME}为MyScript,${MY_EXT}为.sh:
脚本:
#!/bin/bash
set -e
MY_EXT=".${0##*.}"
ME=$(/usr/bin/basename "${0}" "${MY_EXT}")
echo "${ME} - ${MY_EXT}"
一些测试:
$ ./MyScript.sh
MyScript - .sh
$ bash MyScript.sh
MyScript - .sh
$ /Users/Jonathan/Scripts/bash/MyScript.sh
MyScript - .sh
$ bash /Users/Jonathan/Scripts/bash/MyScript.sh
MyScript - .sh