背景:
我有一个应以“描述文本ref12345678”的形式获取用户输入的列。我有现有的脚本可以获取参考号,但不幸的是有些用户添加错误而不是"ref12345678"
,而是"ref 12345678"
,"RF12345678"
,"abcd12345678"
或任何变体。当然,错误的格式会破坏一些触发的脚本。
目前我无法控制该字段的用户输入,因此我想稍后在管道中创建脚本以获取该数字。
目前我正用awk '{gsub(/[[:alpha:]]/, "")}; 1'
剥离字母,但替换似乎是一种效率低下的解决方案。 (我知道我也可以使用sed -n 's/.*[a-zA-Z]//p'
和tr -d '[[:alpha:]]'
执行此操作,但它们基本相同,我希望获得额外的可编程性。
问题是,有没有办法将awk设置为只打印字符串中的数字,或者将字符串设置为字符串中的数字项? (或替代真的是解决这个问题的最有效方法)。
总结一下:如何使用awk $ echo "ref12345678"
仅打印“12345678”而不进行替换?
答案 0 :(得分:23)
如果awk 不必须:
grep -o '[0-9]\+'
示例:
kent$ echo "ref12345678"|grep -o '[0-9]\+'
12345678
以 awk 为例:
kent$ echo "ref12345678"|awk -F'[^0-9]*' '$0=$2'
12345678
答案 1 :(得分:5)
您也可以尝试使用awk,假设字符串中只有一个数字:
awk '{print ($0+0)}'
这会将整个字符串转换为数字,并且将保留仅实现符合数字描述的值的awk的方式。例如:
echo "19 trees"|awk '{print ($0+0)}'
将产生:
19
答案 2 :(得分:1)
另一个选项(假设GNU awk
)涉及将非数字正则表达式指定为分隔符
awk -F '[^0-9]+' '{OFS=" "; for(i=1; i<=NF; ++i) if ($i != "") print($i)}'
答案 3 :(得分: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..
答案 4 :(得分:0)
在AWK中,您可以指定多种条件,例如:
($3~/[[:digit:]+]/ && $3 !~/[[:alpha:]]/ && $3 !~/[[:punct:]]/ ) {print $3}
将仅显示数字,没有任何字母和标点符号。 与 !〜 表示 不包含任何 。