问题
Let's say you want the best pattern to extract both name and version from a jar filename. I got something not so bad which works on regexr but not with bash. This is because bash does not support non-greedy regex. So how should one handle this?
#!/bin/bash
filename="./log4j-enhanced-3.5.100-v20130422-1538.jar"
if [[ "$filename" =~ \.\/(.*?)-([0-9].*)\.jar ]]; then
echo "name = ${BASH_REMATCH[1]}"
echo "version = ${BASH_REMATCH[2]}"
fi
# expected :
# name = log4j-enhanced
# version = 3.5.100-v20130422-1538
Usage of unix utilities is ok, but please make it readable.
回答1:
With GNU bash's Parameter Expansion :
filename="./log4j-enhanced-3.5.100-v20130422-1538.jar"
filename="${filename#./}"
name="${filename%%-[0-9]*}"
version="${filename#$name-}"
version="${version%.jar}"
echo "name = $name"
echo "version = $version"
Output:
name = log4j-enhanced version = 3.5.100-v20130422-1538
回答2:
You can use
filename="./log4j-enhanced-3.5.100-v20130422-1538.jar"
if [[ "$filename" =~ [.]/([[:alnum:]-]*)-([0-9].*)[.]jar ]]; then
echo "name = ${BASH_REMATCH[1]}"
echo "version = ${BASH_REMATCH[2]}"
fi
See the Ideone demo
The [[:alnum:]-]*
will greedily match alphanumeric and hyphen characters up to a hyphen followed with a digit.
回答3:
If you want to accomplish the same thing without using Bash's special features, here is what you can do:
#!/bin/sh
filename="./log4j-enhanced-3.5.100-v20130422-1538.jar"
regex='.\/\(.*\)-\([0-9]\+\.[0-9]\+.*\)\.jar'
name="$(echo $filename | sed -e "s/$regex/\1/")"
version="$(echo $filename | sed -e "s/$regex/\2/")"
echo " name: $name"
echo "version: $version"
Output:
name: log4j-enhanced
version: 3.5.100-v20130422-1538
来源:https://stackoverflow.com/questions/37490013/parse-jar-filenames