如何从字符串中提取数字?

时间:2013-07-26 14:12:05

标签: linux bash shell substring sh

我有字符串包含路径

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

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

提取第一个数字:

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

提取第二个数字:

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

因此,要提取参数,我必须分两步完成。如何一步提取数字?

10 个答案:

答案 0 :(得分:9)

提取所有单个数字并通过 -

打印每个管道的一个数字
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

答案 1 :(得分:7)

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

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

答案 2 :(得分:4)

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

$ string="toto.titi.12.tata.2.abc.def"
$ read num1 num2 <<<${string//[^0-9]/ }
$ echo "$num1 / $num2"
12 / 2

这当然取决于$string的格式。但至少在你提供的例子中,似乎有效。

这可能优于需要子壳的anubhava的awk解决方案。我也喜欢chepner的解决方案,但正则表达式更重&#34;比参数扩展(虽然显然更精确)。 (请注意,在上面的表达式中,[^0-9]可能看起来像正则表达式原子,但它不是。)

您可以在bash手册页中阅读有关此表单或参数扩展的信息。请注意,${string//this/that}(以及<<<)是一种基础,并且与传统的Bourne或posix shell不兼容。

答案 3 :(得分:2)

使用awk:

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

答案 4 :(得分:2)

您也可以使用sed:

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

这里,sed取代

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

输出将是:

toto.titi..tata..abc.def

答案 5 :(得分:1)

如果您提供了您想要获得的输出,那么这将更容易回答。如果你的意思是想要只获取字符串中的数字,并删除其他所有内容,则可以执行以下操作:

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

如果你澄清一下,我可以提供更多帮助。

答案 6 :(得分:0)

使用正则表达式匹配:

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

答案 7 :(得分:0)

您可以使用'cut'添加另一种方法来实现此目的,

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

这为您提供以下输出: 12 2

答案 8 :(得分:0)

这里很短:

string="toto.titi.12.tata.2.abc.def"
id=$(echo "$string" | grep -o -E '[0-9]+')

echo $id // => output: 12 2

数字之间有空格。 希望对您有帮助...

答案 9 :(得分:0)

修复换行问题(对于Mac终端):

cat temp.txt | tr '\n' ' ' | sed -e 's/[^0-9]/ /g' -e 's/^ *//g' -e 's/ *$//g' | tr -s ' ' | sed $'s/ /\\\n/g'