Bash 的最后一个索引
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16153446/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Bash last index of
提问by carlspring
Sorry for the lame bash question, but I can't seem to be able to work it out.
很抱歉这个蹩脚的 bash 问题,但我似乎无法解决。
I have the following simple case:
我有以下简单案例:
I have variable like
artifact-1.2.3.zipI would like to get a sub-string between the hyphen and the last index of the dot (both exclusive).
我有像这样的变量
artifact-1.2.3.zip我想在连字符和点的最后一个索引(都是独占的)之间获得一个子字符串。
My bash skill are not too strong. I have the following:
我的 bash 技能不是太强。我有以下几点:
a="artifact-1.2.3.zip"; b="-"; echo ${a:$(( $(expr index "$a" "$b" + 1) - $(expr length "$b") ))}
Producing:
生产:
1.2.3.zip
How do I remove the .zippart as well?
我如何删除.zip零件?
采纳答案by bobbogo
$ a="artifact-1.2.3.zip"; a="${a#*-}"; echo "${a%.*}"
‘#pattern' removes patternso long as it matches the beginningof $a.
The syntax of patternis similar to that used in filename matching.
In our case,
“#模式”中移除了图案,只要比赛开始的$a。模式的语法类似于文件名匹配中使用的语法。在我们的例子中,
*is any sequence of characters.-means a literal dash.- Thus
#*-matches everything up to, and including, the firstdash. - Thus
${a#*-}expands to whatever$awould expand to, except thatartifact-is removed from the expansion, leaving us with1.2.3.zip.
*是任何字符序列。-表示字面破折号。- 因此
#*-匹配所有内容,包括第一个破折号。 - 因此
${a#*-}扩展到任何$a将扩展到的东西,除了artifact-从扩展中删除之外,留下1.2.3.zip.
Similarly, ‘%pattern' removes patternso long as it matches the endof the expansion.
In our case,
类似地,只要匹配扩展的结尾,' %pattern' 就会删除模式。在我们的例子中,
.a literal dot.*any sequence of characters.- Thus
%.*is everything including the lastdot up to the end of the string. - Thus if
$aexpands to1.2.3.zip, then${a%.*}expands to1.2.3.
.一个字面意思。*任何字符序列。- 因此
%.*,包括最后一个点到字符串末尾的所有内容都是如此。 - 因此,如果
$a扩展为1.2.3.zip,则${a%.*}扩展为1.2.3。
Job done.
任务完成。
The man page content for this is as follows (at least on my machine, YMMV):
手册页内容如下(至少在我的机器上,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!
哼!
EDIT
编辑
Kudos to @x4d for the detailed answer. Still think people should RTFM though. If they don't understand the manual, then post another question.
感谢@x4d 提供的详细答案。仍然认为人们应该 RTFM。如果他们不理解手册,则发布另一个问题。
回答by aks
The bashman page section titled "Variable Substitution" describes using ${var#pattern}, ${var##pattern}, ${var%pattern}, and ${var%%pattern}.
在bash题为“男人节页变量替换”描述了使用${var#pattern},${var##pattern},${var%pattern},和${var%%pattern}。
Assuming that you have a variable called filename, e.g.,
假设您有一个名为 的变量filename,例如,
filename="artifact-1.2.3.zip"
then, the following are pattern-based extractions:
然后,以下是基于模式的提取:
% echo "${filename%-*}"
artifact
% echo "${filename##*-}"
1.2.3.zip
Why did I use ##instead of #?
为什么我用##而不是#?
If the filename could possibly contain dashes within, such as:
如果文件名中可能包含破折号,例如:
filename="multiple-part-name-1.2.3.zip"
then compare the two following substitutions:
然后比较以下两个替换:
% echo "${filename#*-}"
part-name-1.2.3.zip
% echo "${filename##*-}"
1.2.3.zip
Once having extracted the version and extension, to isolate the version, use:
提取版本和扩展后,要隔离版本,请使用:
% verext="${filename##*-}"
% ver="${verext%.*}"
% ext="${verext##*.}"
% echo $ver
1.2.3
% echo $ext
zip
回答by anubhava
Using Bash RegEx feature:
使用 Bash RegEx 功能:
>str="artifact-1.2.3.zip"
[[ "$str" =~ -(.*)\.[^.]*$ ]] && echo ${BASH_REMATCH[1]}

