我有一个包含路径的字符串。
string="toto.titi.12.tata.2.abc.def"
我想从这个字符串中提取数字。要提取第一个数字:tmp="${string#toto.titi.*.}"
num1="${tmp%.tata*}"
提取第二个数字:tmp="${string#toto.titi.*.tata.*.}"
num2="${tmp%.abc.def}"
所以要提取参数,我需要分两步来完成。如何用一步提取数字?
tr
删除所有非数字字符,如下所示:echo toto.titi.12.tata.2.abc.def | tr -d -c 0-9
122
。有什么方法可以将它们分开吗? - ghoti将所有单个数字提取出来,并逐行打印一个数字单词,可以通过管道符 - 进行传输。
tr '\n' ' ' | sed -e 's/[^0-9]/ /g' -e 's/^ *//g' -e 's/ *$//g' | tr -s ' ' | sed 's/ /\n/g'
步骤:
tr '\n' ' '
sed -e 's/[^0-9]/ /g'
-e 's/^ *//g'
-e 's/ *$//g'
tr -s ' '
sed 's/ /\n/g'
示例:
echo -e " this 20 is 2sen\nten324ce 2 sort of" | tr '\n' ' ' | sed -e 's/[^0-9]/ /g' -e 's/^ *//g' -e 's/ *$//g' | tr -s ' ' | sed 's/ /\n/g'
将会打印输出
20
2
324
2
这是一个简短的内容:
string="toto.titi.12.tata.2.abc.def"
id=$(echo "$string" | grep -o -E '[0-9]+')
echo $id // => output: 12 2
带有数字之间的空格。 希望能帮到您...
$ string="toto.titi.12.tata.2.abc.def"
$ read num1 num2 <<<${string//[^0-9]/ }
$ echo "$num1 / $num2"
12 / 2
当然,这取决于$string
的格式。但至少对于您提供的示例,它似乎有效。
与anubhava的awk解决方案相比,这可能更为优越,因为后者需要一个子shell。我也喜欢chepner的解决方案,但是正则表达式比参数展开“重”(虽然显然要更精确)。 (请注意,在上面的表达式中,[^ 0-9] 可能看起来像是正则表达式原子,但实际上不是。)
您可以在bash手册中了解有关此形式或参数展开的信息。请注意, $ {string // this / that} (以及<<< )是一种bashism,不兼容传统的Bourne或posix shell。
$string
的格式”具体是什么意思?我想不出任何会破坏它的例子。 - PesaTheaa12aa34aa56
,而你只读取两个变量,那么尾随的数字会被添加到最后一个变量中,用空格分隔。如果这是一个问题,那么更好的解决方案可能是将字符串读入数组中:read -a nums <<<"${string//[^0-9]/ }"
。 - ghoti$ str="toto.titi.12.tata.2.abc.def"
$ arr=( ${str//[!0-9]/ } )
$ echo "${arr[@]}"
12 2
d@AirBox:~$ string="toto.titi.12.tata.2.abc.def"
d@AirBox:~$ echo "${string//[a-z,.]/}"
122
echo "toto.titi.12.tata.2.abc.def" | sed 's/[0-9]*//g'
[0-9]
)*
)/
之间没有任何东西),g
表示全局。输出将会是:
toto.titi..tata..abc.def
^
来反转匹配:echo "toto.titi.12.tata.2.abc.def" | sed 's/[^0-9]*//g'
。 - Dario Seidl你好,这是另一种使用“cut”命令的方法:
echo $string | cut -d'.' -f3,5 | tr '.' ' '
12 2
string="toto.titi.12.tata.2.abc.def"
[[ $string =~ toto\.titi\.([0-9]+)\.tata\.([0-9]+)\. ]]
# BASH_REMATCH[0] would be "toto.titi.12.tata.2.", the entire match
# Successive elements of the array correspond to the parenthesized
# subexpressions, in left-to-right order. (If there are nested parentheses,
# they are numbered in depth-first order.)
first_number=${BASH_REMATCH[1]}
second_number=${BASH_REMATCH[2]}
arr=( $(echo $string | awk -F "." '{print $3, $5}') )
num1=${arr[0]}
num2=${arr[1]}
echo ${string} | grep -o -E "[0-9]+"
是最简洁且易于理解的方法(大多数人都知道grep)。来源:https://dev59.com/hGMm5IYBdhLWcg3wFL7s#52947167 - Trevor Boyd Smith