正则表达式“^[[:digit:]]$”在 AWK/GAWK 中未按预期工作

dig*_*123 4 awk gnu gawk character-class

我在 RHEL 上的 GAWK 版本是:

gawk-3.1.5-15.el5
Run Code Online (Sandbox Code Playgroud)

我想打印一行,如果它的第一个字段包含所有数字(没有特殊字符,甚至要考虑空格)

Example:

echo "123456789012345,3" | awk -F, '{if ($1 ~ /^[[:digit:]]$/)  print $0}'

Output:
Nothing

Expected Output:
123456789012345,3
Run Code Online (Sandbox Code Playgroud)

这里出了什么问题?我的 AWK 版本不理解 GNU 字符类吗?请帮忙

Ini*_*ian 5

要匹配字符[[:digit:]]类中的多个数字,请添加+,这意味着匹配 中的一个或多个数字$1

echo "123456789012345,3" | awk -F, '{if ($1 ~ /^([[:digit:]]+)$/)  print $0}'
123456789012345,3
Run Code Online (Sandbox Code Playgroud)

满足您的要求。

一种更惯用的方法(如评论中建议的那样)是删除print并涉及行上的直接匹配并打印它,

echo "123456789012345,3" | awk -F, '$1 ~ /^([[:digit:]]+)$/'
123456789012345,3
Run Code Online (Sandbox Code Playgroud)

更多的例子也证明了这一点,

echo "a1,3" | awk -F, '$1 ~ /^([[:digit:]]+)$/'
Run Code Online (Sandbox Code Playgroud)

(和)

echo "aa,3" | awk -F, '$1 ~ /^([[:digit:]]+)$/'
Run Code Online (Sandbox Code Playgroud)

不根据要求产生任何输出

另一种POSIX对数字进行严格长度检查的合规方法可以通过如下所示的方式来实现,其中{3}表示匹配长度。

echo "123,3" |  awk --posix -F, '$1 ~ /^[0-9]{3}$/'
123,3
Run Code Online (Sandbox Code Playgroud)

(和)

echo "12,3" |  awk --posix -F, '$1 ~ /^[0-9]{3}$/'
Run Code Online (Sandbox Code Playgroud)

不产生任何输出。

如果您使用的是相对较新版本的bashshell,它支持使用上面的字符类的本regEx机运算符~POSIX例如

#!/bin/bash

while IFS=',' read -r row1 row2
do
   [[ $row1 =~ ^([[:digit:]]+)$ ]] && printf "%s,%s\n" "$row1" "$row2"
done < file
Run Code Online (Sandbox Code Playgroud)

对于输入文件来说file

$ cat file
122,12
a1,22
aa,12
Run Code Online (Sandbox Code Playgroud)

该脚本产生,

$ bash script.sh
122,12
Run Code Online (Sandbox Code Playgroud)

虽然这可行,但bash regEx使用字符串操作的相对直接的方式可能会慢一些,就像

while IFS=',' read -r row1 row2
do
   [[ -z "${row1//[0-9]/}" ]] && printf "%s,%s\n" "$row1" "$row2"
done < file
Run Code Online (Sandbox Code Playgroud)

删除"${row1//[0-9]/}"该行中的所有数字,并且仅当变量中没有其他字符时条件才变为 true。

  • 由于某些原因,专家鼓励使用更惯用的 `awk`,如 `echo "123456789012345,3" | awk -F, '$1 ~ /^[[:数字:]]*$/'`。这里的“print”不是多余的吗? (3认同)
  • @sjsam:当然可以!有时,当使用OP自己的命令并在其之上进行修改时,一些微小的细节会丢失。不过不错的收获!请随意编辑它,作为您的有效观点! (2认同)