繁体   English   中英

如何删除 bash 中的所有文件扩展名?

[英]How to remove all file extensions in bash?

x=./gandalf.tar.gz
noext=${x%.*}
echo $noext

这打印./gandalf.tar ,但我只需要./gandalf 我什至可能有像./gandalf.tar.abc这样有更多扩展名的文件。

我只需要第一个之前的部分.

如果你想给sed一个机会,那么:

x='./gandalf.tar.a.b.c'
sed -E 's~(.)\..*~\1~g' <<< "$x"

./gandalf

或者 bash 中的两步过程:

x="${s#./}"
echo "./${x%%.*}"

./gandalf

使用bashextglob shell 选项:

shopt -s extglob
x=./gandalf.tar.a.b.c
noext=${x%%.*([!/])}
echo "$noext"

这将删除不包含/字符的子字符串,包括第一个. 特点。 也适用于x=/pq.12/r/gandalf.tar.abc

如果您的 bash 版本支持正则表达式,也许正则表达式是最好的方法,因为它不会分叉新进程。

此正则表达式适用于任何前缀路径,并考虑名称中第一个字符为点的文件(隐藏文件):

[[ "$x" =~ ^(.*/|)(.[^.]*).*$ ]] && \
noext="${BASH_REMATCH[1]}${BASH_REMATCH[2]}"

正则表达式解释

第一组捕获直到最后一个/包含的所有内容(正则表达式在 bash 中是贪婪的),或者如果字符串中没有/则什么也没有。 然后第二组捕获第一组之前的所有内容. , 除外。

字符串的其余部分没有被捕获,因为我们想要摆脱它。

最后,我们连接路径和剥离的名称。

笔记

目前尚不清楚您想对以. 隐藏文件)。 我修改了正则表达式以保留. 如果存在,因为这似乎是最合理的事情。 例如

x="/foo/bar/.myinitfile.sh"

变成/foo/bar/.myinitfile

如果性能不是问题,例如像这样:

fil=$(basename "$x")
noext="$(dirname "$x")"/${fil%%.*}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM