awk' s ^(插入符号)排除是如何工作的?

时间:2016-09-05 11:42:35

标签: regex linux awk

我在下面显示了(在fedora 24上运行):

输入示例:

/sys/devices/system/memory/memory101/state:offline
/sys/devices/system/memory/memory104/state:offline
/sys/devices/system/memory/memory107/state:offline

在输入上执行AWK命令:

grep offline data/onlineMemory | awk -F '[^0-9]+' {'print $2'}

,输出如下:

101
104
107

但是当我打印awk' $1时,我什么也看不见。线路的其他部分在哪里消失了?

为什么$2设置为数字?我认为awk中的^会否定角色。

2 个答案:

答案 0 :(得分:5)

这很奇怪,但很正常:因为您要将字段分隔符设置为[^0-9]+awk将其理解为:所有内容都是除数字之外的字段分隔符。

#field1                                              field3
#<|                                                  |>
#  /sys/devices/system/memory/memory101/state:offline
#  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   ^^^^^^^^^^^^^^
#              FS                   ^^^       FS
#                                   field2

这样,字符串中的几乎所有内容都成为字段分隔符:

$ awk -F '[^0-9]+' '{for (i=1;i<=NF;i++) printf "line=%d. field num %d is --> %s\n", NR, i, $i}' file
line=1. field num 1 is --> 
line=1. field num 2 is --> 101
line=1. field num 3 is --> 
line=2. field num 1 is --> 
line=2. field num 2 is --> 104
line=2. field num 3 is --> 
line=3. field num 1 is --> 
line=3. field num 2 is --> 107
line=3. field num 3 is --> 

为什么会这样?因为awk设置字段的方式:
它将第一个设置为FS的所有内容,然后是第一个到第二个FS的第二个,依此类推;最后,最后一个字段($NF)包含从最后一个FS到记录结尾的所有内容:

$ awk -F ';' '{for (i=1;i<=NF;i++) printf "line=%d. field num %d is --> %s\n", NR, i, $i}' <<< ";hello;"
line=1. field num 1 is --> 
line=1. field num 2 is --> hello
line=1. field num 3 is --> 

所以在这种情况下,你使FS变得相当复杂,可以用这个例子来概括,其中FS不是3

$ awk -F '[^3]+' '{for (i=1;i<=NF;i++) printf "line=%d. field num %d is --> %s\n", NR, i, $i}' <<< "abcde3fghi"
line=1. field num 1 is --> 
line=1. field num 2 is --> 3
line=1. field num 3 is --> 

所以awk在这种情况下做的是使用FS abcde3fghi拆分字符串anything but 3,使第一个FS之前的所有内容成为第一个字段(因此为空) FS最后一次出现之后的所有内容(因此也是空的)。这让我们只剩下一个非空的领域,第二个。

答案 1 :(得分:0)

在这一行:

/sys/devices/system/memory/memory101/state:offline

字段分隔符为/sys/devices/system/memory/memory,因为其中没有数字。

在分隔符的左侧,没有任何内容,右侧是您的号码,因为它不适合分隔符正则表达式