我想分别获取文件名(不带扩展名)和扩展名。
到目前为止,我找到的最佳解决方案是:
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解释器。
有更好的主意吗?
为了使dir更有用(在没有指定路径的本地文件作为输入的情况下),我执行了以下操作:
# Substring from 0 thru pos of filename
dir="${fullpath:0:${#fullpath} - ${#filename}}"
if [[ -z "$dir" ]]; then
dir="./"
fi
这允许您执行一些有用的操作,如在输入文件basename中添加后缀,如下所示:
outfile=${dir}${base}_suffix.${ext}
testcase: foo.bar
dir: "./"
base: "foo"
ext: "bar"
outfile: "./foo_suffix.bar"
testcase: /home/me/foo.bar
dir: "/home/me/"
base: "foo"
ext: "bar"
outfile: "/home/me/foo_suffix.bar"
您可以使用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
pax> echo a.b.js | sed 's/\.[^.]*$//'
a.b
pax> echo a.b.js | sed 's/^.*\.//'
js
工作正常,因此您可以使用:
pax> FILE=a.b.js
pax> NAME=$(echo "$FILE" | sed 's/\.[^.]*$//')
pax> EXTENSION=$(echo "$FILE" | sed 's/^.*\.//')
pax> echo $NAME
a.b
pax> echo $EXTENSION
js
顺便说一下,这些命令的工作原理如下。
NAME命令将一个“.”字符后接任意数量的非“.”字,直到行尾,但不包含任何内容(即,从最后的“.”到行尾,包括首尾)。这基本上是一个使用正则表达式技巧的非贪婪替换。
EXTENSION命令将任意数量的字符替换为行开头的“.”字符,而不使用任何字符(即,它删除从行开头到最后一个点的所有内容,包括所有内容)。这是一个贪婪的替代,这是默认操作。