如何从string中提取数字?

我有string包含一个path

string="toto.titi.12.tata.2.abc.def" 

我只想从这个string中提取数字。

提取第一个数字:

 tmp="${string#toto.titi.*.}" num1="${tmp%.tata*}" 

提取第二个数字:

 tmp="${string#toto.titi.*.tata.*.}" num2="${tmp%.abc.def}" 

所以要提取一个参数,我必须分两步来完成。 如何提取一个数字一步?

提取所有的个人号码,并通过每行打印一个数字字 –

 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'
  • 按顺序挤压空格为1空格: 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 

您可以使用tr删除所有非数字字符,如下所示:

 echo toto.titi.12.tata.2.abc.def | tr -d -c 0-9 

参数扩展似乎是一天的顺序。

 $ 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不兼容。

使用awk:

 arr=( $(echo $string | awk -F "." '{print $3, $5}') ) num1=${arr[0]} num2=${arr[1]} 

你也可以使用sed:

 echo "toto.titi.12.tata.2.abc.def" | sed 's/[0-9]*//g' 

在这里,sed取代

  • 任何数字(类[0-9]
  • 重复任意次数( *
  • 没有什么(第二和第三/之间没有什么),
  • g代表全球。

输出将是:

 toto.titi..tata..abc.def 

如果你提供了你正在寻找的输出,这将更容易回答。 如果你的意思是你想从字符串中取出数字,并删除所有其他的东西,你可以这样做:

 d@AirBox:~$ string="toto.titi.12.tata.2.abc.def" d@AirBox:~$ echo "${string//[az,.]/}" 122 

如果你澄清一点,我可能会帮助更多。

使用正则表达式匹配:

 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]} 

您好添加另一种方式来做到这一点使用“剪切”

 echo $string | cut -d'.' -f3,5 | tr '.' ' ' 

这给你以下输出:12 2