23

背景:
我有一列应该以“描述文本 ref12345678”的形式获取用户输入。我有现有的脚本来获取参考号,但不幸的是,有些用户错误地添加了它,所以它"ref12345678"可以是"ref 12345678",或任何变体。自然,错误的格式会破坏一些触发的脚本。目前我无法控制用户对此字段的输入,所以我想稍后在管道中制作脚本只是为了获取数字。"RF12345678""abcd12345678"

目前我正在用 剥离字母awk '{gsub(/[[:alpha:]]/, "")}; 1',但替换似乎是一种低效的解决方案。(我知道我也可以这样做sed -n 's/.*[a-zA-Z]//p'tr -d '[[:alpha:]]'但是它们本质上是相同的,我想要 awk 以获得额外的可编程性)。

问题是,有没有办法将 awk 设置为仅打印字符串中的数字,或者为字符串中的数字项设置分隔符?(或者替代真的是这个问题最有效的解决方案)。

总而言之:我如何使用 awk$ echo "ref12345678"仅打印“12345678”而不进行替换?

4

5 回答 5

33

如果 awk不是必须的:

grep -o '[0-9]\+'

例子:

kent$ echo "ref12345678"|grep -o '[0-9]\+'
12345678

awk为例:

kent$ echo "ref12345678"|awk -F'[^0-9]*' '$0=$2'     
12345678
于 2013-05-17T21:56:50.377 回答
11

您还可以使用 awk 尝试以下操作,假设字符串中只有一个数字:

awk '{print ($0+0)}'

这会将您的整个字符串转换为数字,并且 awk 的实现方式只会留下符合数字描述的值。例如:

echo "19 trees"|awk '{print ($0+0)}'

将产生:
19

于 2017-02-16T18:47:41.220 回答
4

在 AWK 中,您可以指定多个条件,例如:


($3~/[[:digit:]+]/ && $3 !~/[[:alpha:]]/ && $3 !~/[[:punct:]]/ ) {print $3}

将只显示没有任何字母和标点符号的数字。with !~表示不包含任何.

于 2019-03-19T13:32:12.663 回答
2

另一个选项(假设GNU awk)涉及指定非数字正则表达式作为分隔符

awk -F '[^0-9]+' '{OFS=" "; for(i=1; i<=NF; ++i) if ($i != "") print($i)}'
于 2013-05-17T22:19:27.857 回答
1

grep 完美运行:

$ echo "../Tin=300_maxl=9_rdx=1.1" | grep -Eo '[+-]?[0-9]+([.][0-9]+)?'
300
9
1.1

分步说明:

-E

使用扩展的正则表达式。

-o

只返回匹配项,而不是上下文

[+-]?[0-9]+([.][0-9]+)?+

匹配编号被标识为:

[+-]?

可选的前导标志

[0-9]+

一个或多个数字

([.][0-9]+)?

一个可选的句点,后跟一个或多个数字。

将输出放在数组中很方便

arr=($(echo "../Tin=300_maxl=9_rdx=1.1" | grep -Eo '[+-]?[0-9]+([.][0-9]+)?'))

然后像这样使用它

Tin=${arr[0]}
maxl=${arr[1]}
etc..
于 2021-04-14T07:48:43.370 回答