我想分别获取文件名(不带扩展名)和扩展名。
到目前为止,我找到的最佳解决方案是:
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解释器。
有更好的主意吗?
您可以使用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
这里有一些替代建议(主要是awk),包括一些高级用例,比如提取软件包的版本号。
请注意,如果输入稍有不同,其中一些可能会失败,因此任何使用这些输入的人都应验证其预期输入,并根据需要调整正则表达式。
f='/path/to/complex/file.1.0.1.tar.gz'
# Filename : 'file.1.0.x.tar.gz'
echo "$f" | awk -F'/' '{print $NF}'
# Extension (last): 'gz'
echo "$f" | awk -F'[.]' '{print $NF}'
# Extension (all) : '1.0.1.tar.gz'
echo "$f" | awk '{sub(/[^.]*[.]/, "", $0)} 1'
# Extension (last-2): 'tar.gz'
echo "$f" | awk -F'[.]' '{print $(NF-1)"."$NF}'
# Basename : 'file'
echo "$f" | awk '{gsub(/.*[/]|[.].*/, "", $0)} 1'
# Basename-extended : 'file.1.0.1.tar'
echo "$f" | awk '{gsub(/.*[/]|[.]{1}[^.]+$/, "", $0)} 1'
# Path : '/path/to/complex/'
echo "$f" | awk '{match($0, /.*[/]/, a); print a[0]}'
# or
echo "$f" | grep -Eo '.*[/]'
# Folder (containing the file) : 'complex'
echo "$f" | awk -F'/' '{$1=""; print $(NF-1)}'
# Version : '1.0.1'
# Defined as 'number.number' or 'number.number.number'
echo "$f" | grep -Eo '[0-9]+[.]+[0-9]+[.]?[0-9]?'
# Version - major : '1'
echo "$f" | grep -Eo '[0-9]+[.]+[0-9]+[.]?[0-9]?' | cut -d. -f1
# Version - minor : '0'
echo "$f" | grep -Eo '[0-9]+[.]+[0-9]+[.]?[0-9]?' | cut -d. -f2
# Version - patch : '1'
echo "$f" | grep -Eo '[0-9]+[.]+[0-9]+[.]?[0-9]?' | cut -d. -f3
# All Components : "path to complex file 1 0 1 tar gz"
echo "$f" | awk -F'[/.]' '{$1=""; print $0}'
# Is absolute : True (exit-code : 0)
# Return true if it is an absolute path (starting with '/' or '~/'
echo "$f" | grep -q '^[/]\|^~/'
所有用例都使用原始完整路径作为输入,而不依赖中间结果。