需要帮助理解这段 bash 代码:“${i%.*}_MYSUFFIX.${i##*.}”

需要帮助理解这段 bash 代码:“${i%.*}_MYSUFFIX.${i##*.}”
for i in *.shp; do ; mv -v "${i}" "${i%.*}_MYSUFFIX.${i##*.}" ; done

这个循环_MYSUFFIX在我的目录中的文件扩展名之前插入......很棒的东西,但我很难理解这一点的细节:

"${i%.*}_MYSUFFIX.${i##*.}"

角色扩展/替换???我不知道从哪里开始寻找解释和文档来学习这一点?

答案1

假设i包含testing.an.string.with.dots.shp,只需在你不理解的部分添加一些空格,然后查看结果:

$ echo "${i%.*}   _MYSUFFIX.    ${i##*.}"
testing.an.string.with.dots   _MYSUFFIX.    shp

因此,这些“参数扩展”可以在 bash 手册中找到:

LESS=+/#word man bash

该链接转到“删除匹配的前缀模式”条目,以下条目是“删除匹配的后缀模式”。这些名字暗示了每个人的作用。一个从变量(参数)内容的前面删除字符,另一个从末尾(尾部)删除字符。

单个字符#%删除较短的匹配部分。

双字符##%%删除最长的匹配部分。

因此,a将重现从以点 ( ) 开头的末尾到末尾删除最短字符串"${i%.*}"的内容。这仅仅意味着:“删除扩展名(和点)”。$i.

A"${i##*.}"将重现 的值,$i同时从前面删除与后跟点的任何内容匹配的最长字符串。简单来说就是:只保留扩展名。

然后,所有三个部分连接成一个字符串。

答案2

所以 tl;dr 来自该手册:

i=bob.was.here.shp
nameFront="${i%.*}" # Deletes shortest match of ".*" from back of $i, one "." only
echo Front=$nameFront
nameExt=${i##*.}    # Deletes longest match of "*." from front of $i, so include "."'s
echo Ext=$nameExt
echo New="${nameFront}_MYSUFFIX.${nameExt}"


Giving:
Front=bob.was.here
Ext=shp
New=bob.was.here_MYSUFFIX.shp

答案3

它被称为“bash 中的字符串操作”

这是一本关于它的非常好的教科书:
https://tldp.org/LDP/abs/html/string-manipulation.html

相关内容