我试图使用重复符号 {n} 打印这些行,但它不起作用。为了。例如我想打印长度为 4 个字符的所有行
awk '/^.{4}$/' test_data
上面的代码没有打印该内容。如何修复它以便我可以使用重复符号?我知道像awk '/^....$/' test_data
and 这样的替代方案awk 'length ==3 ' test_data
答案1
根据GNU Awk 用户指南:功能历史,在 3.0 版本中添加了对正则表达式范围运算符的支持,但最初需要显式命令行选项
新的命令行选项:
- 新的命令行选项:
- --lint-old 选项用于警告原始版本 7 Unix 版本的 awk 中不可用的构造(请参阅 V7/SVR3.1)。
- BWK awk 中的 -m 选项。 (Brian 当时还在贝尔实验室。)后来这句话从他的 awk 和 gawk 中删除了。
- --re-interval 选项用于在正则表达式中提供间隔表达式(请参阅正则表达式运算符)。
- 添加了 --traditional 选项作为 --compat 的更好名称(请参阅选项)。
在gawk
4.0中,
区间表达式成为默认正则表达式的一部分
由于您使用的是gawk
3.x,因此您需要使用
awk --re-interval '/^.{4}$/'
或者
awk --posix '/^.{4}$/'
或者(感谢@StéphaneChazelas)如果您想要一个可移植的解决方案,请使用
POSIXLY_CORRECT=anything awk '/^.{4}$/'
(因为--posix
或--re-interval
会在其他实现中导致错误awk
)。
答案2
ERE(扩展正则表达式awk
如or使用的egrep
)最初没有{x,y}
。它首先在 BRE 中引入(由grep
or使用sed
),但其\{x,y\}
语法不会破坏向后可移植性。
但是当它使用该语法添加到 ERE 时{x,y}
,它确实破坏了向后可移植性,因为foo{2}
RE 匹配了之前不同的东西。
所以一些实现选择不这样做。您会发现/bin/awk
,/bin/nawk
并且/bin/egrep
在 Solaris 上仍然不遵守它(您需要使用/usr/xpg4/bin/awk
或/usr/xpg4/bin/grep -E
)。对于 FreeBSDawk
来说是一样的nawk
(基于awk
由 Brian Kernighan维护(k
中awk
))。
对于 GNUawk
,直到最近(版本 4.0),您必须使用 来调用POSIXLY_CORRECT=anything awk '/^.{4}$/'
它才能兑现它。mawk
仍然不尊重它。
请注意,该运算符只是语法糖。.{3,5}
总是可以写成....?.?
example (当然,这样{3,5}
更易读,而相当于 的情况(foo.{5,9}bar){123,456}
会更糟)。
答案3
awk
这与 GNU (gawk)的预期一致:
$ printf 'abcd\nabc\nabcde\n' | gawk '/^.{4}$/'
abcd
但是失败了,mawk
它更接近 POSIX awk
,并且 AFAIK,它是 Ubuntu 系统上的默认值:
$ printf 'abcd\nabc\nabcde\n' | mawk '/^.{4}$/'
$ ## prints nothing
因此,一个简单的解决方案是使用gawk
而不是awk
.该{n}
表示法不是 POSIX BRE(基本正则表达式)语法的一部分。这就是为什么grep
这里也失败的原因:
$ printf 'abcd\nabc\nabcde\n' | grep '^.{4}$'
$
然而,它是 ERE(扩展正则表达式)的一部分:
$ printf 'abcd\nabc\nabcde\n' | grep -E '^.{4}$'
abcd
。他们使用旧版本的 ERE 根据史蒂芬的回答。无论如何,要么您显然使用的版本mawk
我不知道or POSIX使用哪种正则表达式风格awk
,但我猜它是 BREawk
不实现 ERE,要么您的输入实际上没有任何包含 4 个字符的行。例如,由于您看不到的空白或 unicode 字形,可能会发生这种情况。