Bash latest index

Sorry for the chronic bash question, but I can't handle it.

I have the following simple case:

  • I have a variable like artifact-1.2.3.zip

  • I would like to get a substring between the hyphen and the last dot index (both exclusive).

My bash skill is not too strong. I have the following:

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

Production:

 1.2.3.zip 

How to remove .zip part?

+6
source share
4 answers
 $ a="artifact-1.2.3.zip"; a="${a#*-}"; echo "${a%.*}" 

' # pattern deletes the pattern if it matches the start of $a . The syntax of the template is similar to the syntax used when matching file names. In our case

  • * - any sequence of characters.
  • - means a literal dash.
  • Thus, #*- matches everything up to the first dash, including and including.
  • So ${a#*-} expands to the point that $a expands to, except that artifact- is removed from the decomposition, leaving us with 1.2.3.zip .

Similarly, the pattern ' % deletes the pattern if it matches the end of the extension. In our case

  • . literal point.
  • * any sequence of characters.
  • So %.* Is everything, including the last dot to the end of the line.
  • Thus, if $a expands to 1.2.3.zip , then ${a%.*} Expands to 1.2.3 .

The task is completed.

The contents of the man page for this is as follows (at least on my machine, 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.

NTN!

EDIT

Claims to @ x4d for a detailed answer. However, people think that RTFM. If they do not understand the manual, then post another question.

+4
source

A section of the bash man page called Variable Replacement describes the use of ${var#pattern} , ${var##pattern} , ${var%pattern} and ${var%%pattern} .

Assuming you have a variable named filename , for example,

 filename="artifact-1.2.3.zip" 

then the following are deducted based on the patterns:

 % echo "${filename%-*}" artifact % echo "${filename##*-}" 1.2.3.zip 

Why did I use ## instead of # ?

If the file name may contain a dash inside, for example:

 filename="multiple-part-name-1.2.3.zip" 

then compare the following two substitutions:

 % echo "${filename#*-}" part-name-1.2.3.zip % echo "${filename##*-}" 1.2.3.zip 

Once you have extracted the version and extension to isolate the version, use:

 % verext="${filename##*-}" % ver="${verext%.*}" % ext="${verext##*.}" % echo $ver 1.2.3 % echo $ext zip 
+22
source

Using the Bash RegEx Function:

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

I think you can do this:

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

The last step removes the last 4 characters from the string. There is more information on here .

0
source

All Articles