的击最后一个索引(Bash last index of)

2019-08-31 19:05发布

很抱歉的瘸腿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的一部分呢?

Answer 1:

$ a="artifact-1.2.3.zip"; a="${a#*-}"; echo "${a%.*}"

# 模式 ”,只要它的开头匹配删除模式 $a图案的语法是类似于在文件名匹配中使用。 在我们的例子中,

  • *是任何字符序列。
  • -指字面破折号。
  • 因此#*-匹配任何字符,直到并包括第一个冲刺。
  • 因此${a#*-}扩展到任何$a将扩大到,除了artifact-从扩张取出,留给我们1.2.3.zip

类似地,“ % 图案 ”,只要它的膨胀结束相匹配移除图案 。 在我们的例子中,

  • . 文字点。
  • *任何字符序列。
  • 因而%.*是一切,包括最后的点到字符串的结尾。
  • 因此,如果$a扩展到1.2.3.zip ,那么${a%.*}扩展为1.2.3

任务完成。

此手册页内容如下(至少在我的机器,因人而异的):

       ${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。 如果他们不理解本手册,然后张贴另一个问题。



Answer 2:

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


Answer 3:

使用bash正则表达式的功能:

>str="artifact-1.2.3.zip"
[[ "$str" =~ -(.*)\.[^.]*$ ]] && echo ${BASH_REMATCH[1]}


Answer 4:

我认为你可以这样做:

string=${a="artifact-1.2.3.zip"; b="-"; echo ${a:$(( $(expr index "$a" "$b" + 1) - $(expr length "$b") ))}}

substring=${string:0:4}

最后一步将删除字符串中的最后4个字符。 有一些更多的信息在这里 。



文章来源: Bash last index of