对于蹩脚的bash问题感到抱歉,但我似乎无法解决这个问题。
我有以下简单的案例:
我的变量如artifact-1.2.3.zip
我想在连字符和点的最后一个索引之间得到一个子字符串(两者都是独占的)。
我的bash技能不是太强。我有以下内容:
a="artifact-1.2.3.zip"; b="-"; echo ${a:$(( $(expr index "$a" "$b" + 1) - $(expr length "$b") ))}
产:
1.2.3.zip
如何删除.zip
部分?
答案 0 :(得分:23)
标题为“变量替代”的bash
手册页部分介绍了如何使用${var#pattern}
,${var##pattern}
,${var%pattern}
和${var%%pattern}
假设您有一个名为filename
的变量,例如
filename="artifact-1.2.3.zip"
然后,以下是基于模式的提取:
% echo "${filename%-*}"
artifact
% echo "${filename##*-}"
1.2.3.zip
为什么我使用##
代替#
?
如果文件名中可能包含破折号,例如:
filename="multiple-part-name-1.2.3.zip"
然后比较以下两个替换:
% echo "${filename#*-}"
part-name-1.2.3.zip
% echo "${filename##*-}"
1.2.3.zip
提取版本和扩展名后,要隔离版本,请使用:
% verext="${filename##*-}"
% ver="${verext%.*}"
% ext="${verext##*.}"
% echo $ver
1.2.3
% echo $ext
zip
答案 1 :(得分:8)
$ a="artifact-1.2.3.zip"; a="${a#*-}"; echo "${a%.*}"
'#
模式'删除模式,只要它与$a
的开头匹配即可。
pattern 的语法类似于文件名匹配中使用的语法。
在我们的例子中,
*
是任何字符序列。-
表示文字破折号。#*-
会匹配第一个短划线的所有内容。${a#*-}
扩展为$a
扩展到的任何内容,
除了从扩展中删除artifact-
之外,
留下1.2.3.zip
。同样,“%
模式”会删除模式,只要它与扩展的 end 匹配即可。
在我们的例子中,
.
一个字面点。*
任何字符序列。%.*
包括 last 点到字符串末尾的所有内容。$a
扩展为1.2.3.zip
,
然后${a%.*}
扩展为1.2.3
。完成工作。
此手册页内容如下(至少在我的机器上,YMMV):
${parameter#word} ${parameter##word} The word is expanded to produce a pattern just as in pathname expansion. If the pattern matches the beginning of the value of parameter, then the result of the expansion is the expanded value of parameter with the shortest matching pattern (the ``#'' case) or the longest matching pattern (the ``##'' case) deleted. If parameter is @ or *, the pattern removal operation is applied to each positional parameter in turn, and the expansion is the resultant list. If parameter is an array variable subscripted with @ or *, the pattern removal operation is applied to each member of the array in turn, and the expansion is the resultant list. ${parameter%word} ${parameter%%word} The word is expanded to produce a pattern just as in pathname expansion. If the pattern matches a trailing portion of the expanded value of parameter, then the result of the expansion is the expanded value of parameter with the shortest matching pat- tern (the ``%'' case) or the longest matching pattern (the ``%%'' case) deleted. If parameter is @ or *, the pattern removal operation is applied to each positional parameter in turn, and the expansion is the resultant list. If parameter is an array variable subscripted with @ or *, the pattern removal operation is applied to each member of the array in turn, and the expansion is the resultant list.
HTH!
修改强>
得到@ x4d的详细答案。 仍然认为人们应该RTFM。 如果他们不懂手册, 然后发布另一个问题。
答案 2 :(得分:3)
使用Bash RegEx功能:
>str="artifact-1.2.3.zip"
[[ "$str" =~ -(.*)\.[^.]*$ ]] && echo ${BASH_REMATCH[1]}
答案 3 :(得分:0)
我认为你可以这样做:
string=${a="artifact-1.2.3.zip"; b="-"; echo ${a:$(( $(expr index "$a" "$b" + 1) - $(expr length "$b") ))}}
substring=${string:0:4}
最后一步从字符串中删除最后4个字符。有关here的更多信息。