awk 的默认字段分隔符
- 2024-11-14 08:30:00
- admin 原创
- 19
问题描述:
awk 的默认分隔符只有空格吗?
解决方案 1:
以下是适用于所有主要 Awk 实现的实用摘要:
GNU Awk ( ) -一些Linux 发行版中的
gawk
默认设置awk
Mawk( )-某些Linux 发行版中的
mawk
默认设置(例如,早期版本的 Ubuntu crysman报告称 19.04 版本现在附带GNU Awk - 请参阅下面的评论。)awk
BWK
awk
Awk -类 BSD 平台(包括 macOS)的默认设置
在 Linux 上,awk -W version
将告诉您默认的实现awk
是哪种。Awk仅理解
BWK (GNU Awk还理解)。awk --version
`awk -W version`
所有这些实现的最新版本都遵循有关字段分隔符[1](但不遵循记录分隔符)的 POSIX 标准**。
词汇表:
RS
是输入记录分隔符,描述如何将输入分解为记录:
+ POSIX**规定的默认值**是**换行符**,如下所示`
`;也就是说,输入**默认被分成几行。
+ `awk`在的命令行上,`RS`可以指定为`-v RS=<sep>`。
+ POSIX 限制`RS`为*文字、单字符*值,但 GNU Awk 和 Mawk 支持可以*扩展正则表达式的**多字符*值(BWK Awk 不*支持*)。
FS
是输入字段分隔符,描述如何将每个记录拆分成字段;它可以是扩展的正则表达式。
+ 在`awk`的命令行上,`FS`可以指定为`-F <sep>`(或`-v FS=<sep>`)。
+ **POSIX规定的默认值*正式*是一个*空格*(`0x20`),但该空格并非*按字面*意思解释为(唯一)分隔符,而是具有*特殊含义***;见下文。
默认情况下:
任何空格 和/或 制表符和/或换行符都被视为字段分隔符
忽略前导和尾随运行。
POSIX 规范使用空格和制表符的抽象<blank>
,这适用于所有语言环境,但可能包含特定语言环境的附加字符 - 我不知道是否存在这样的语言环境。
请注意,使用默认的输入记录分隔符(RS
),`换行符**通常*不会*作为字段分隔符进入图片**,因为在这种情况下**没有记录*本身* 包含
`**。
然而,换行符作为字段分隔符确实会发挥作用:
当*
RS
设置为一个值时,会导致记录本身*包含`实例**(例如,当
RS`设置为空字符串时;见下文)。一般来说,当该
split()
函数用于将字符串拆分为数组元素时,不需要显式字段分隔符参数。即使在默认值生效的情况下输入记录不包含实例,但是当在来自不同源(例如,通过选项传递的变量或伪文件名)的多行字符串上调用该函数时,如果没有明确的字段分隔符参数,则始终将其视为字段分隔符。`
RS
split()-v
`
重要的非违约考虑因素:
将空字符串分配给
RS
具有特殊含义:它以段落模式读取输入,这意味着输入被按非空行分解为记录,并且忽略前导和尾随的空行。当您为分配除文字空间之外的任何内容
FS
时,的解释FS
会发生根本性的变化:
+ **单个字符或指定字符*集中***的每个字符被***单独*****识别为字段分隔符**- 而不是像默认的那样连续
*运行****。***
- 例如,设置`FS`为`[ ]`- 即使它*实际上*相当于一个空格 - 也会导致每个记录中的每个*单独的*空格实例被视为字段分隔符。
- 为了识别*连续的字符*`+`,必须使用正则表达式量词(重复符号) ;例如,将*连续*`[ ]+`的制表符识别为单个分隔符。
+ ***前导和尾随*分隔符不会被忽略**,而是用来分隔*空*字段。
+ **设置`FS`为*空字符串***意味着记录的**每个*字符*****都是其自己的字段**。
根据POSIX 的规定,如果*
RS
设置为空字符串(段落模式),则换行符*(`)*也*将被视为字段分隔符**,而不管 的值如何
FS`。
[1] 不幸的是,当您使用选项( ) 强制遵循 POSIX 合规性时, GNU Awk 至少在版本 4.1.3 之前遵守有关字段分隔符的过时POSIX 标准:当该选项生效并设置为非空值时,换行符 (实例) 不会被识别为字段分隔符。GNU Awk 手册详细说明了过时的行为(但忽略了提到当设置为空字符串时它不适用)。POSIX 标准在 2008 年进行了更改(参见注释),当 具有其默认值时,也会考虑换行符字段分隔符- 正如 GNU Awk 一直在没有(的情况下所做的那样)。
以下是 2 个验证上述行为的命令:-P
`--posixRS
RS
FS
-P`--posix
-P
在有效并RS
设置为空字符串的情况下,仍然`
`被视为字段分隔符:
`gawk -P -F' ' -v RS='' '{ printf "<%s>, <%s>
", $1, $2 }' <<< $'a
b'`
实际上
-P
,如果非空RS
,`
`则不将其视为字段分隔符 - 这是过时的行为:根据 GNU Awk 维护者的说法,
`gawk -P -F' ' -v RS='|' '{ printf "<%s>, <%s>
", $1, $2 }' <<< $'a
b'`
修复即将到来;预计在版本4.2中(未给出时间框架)。
(向 @JohnKugelman 和 @EdMorton 表示感谢,感谢他们的帮助。)
解决方案 2:
这个问题the default delimiter is only space for awk?
比较模糊,但我会尽力回答您可能提出的两个问题。
该变量的默认值FS
(保存字段分隔符,告诉 awk 在读取记录时如何将记录分隔成字段)是一个空格字符。
awk 用于将记录分隔成字段的东西是“字段分隔符”,它是一个正则表达式,具有一些附加功能,仅当字段分隔符是单个空白字符时才适用。该附加功能是:
在字段拆分期间,前导和尾随空格将被忽略。
字段由连续的空格字符链分隔,包括空格、制表符和换行符。
如果您想使用文字空白字符作为字段分隔符,则必须将其指定为,
[ ]
而不是像在正则表达式中那样仅指定独立的文字空白字符。
除了在读取输入时使用字段分隔符将记录拆分为字段之外,它们还用于其他一些上下文中,例如,的第 3 个参数split()
,因此,了解哪些上下文需要字符串、正则表达式或 fieldsep 并且手册页清楚地指定每一个非常重要。
除其他事项外,以上内容解释了这一点:
$ echo ' a b c ' | awk '{printf "%d: <%s> <%s> <%s>
", NF, $1, $2, $3}'
3: <a> <b> <c>
$ echo ' a b c ' | awk -F' ' '{printf "%d: <%s> <%s> <%s>
", NF, $1, $2, $3}'
3: <a> <b> <c>
$ echo ' a b c ' | awk -F'[ ]' '{printf "%d: <%s> <%s> <%s>
", NF, $1, $2, $3}'
5: <> <a> <b>
因此,如果您不明白为什么前两个产生相同的输出而最后一个产生不同的输出,请询问。
解决方案 3:
让我们看一下 GNU awk 手册页:
FS
— 输入字段分隔符,默认为空格。请参阅上文的字段。
转至Fields部分!
读取每个输入记录时,gawk 会将记录拆分为字段,并使用变量的值
FS
作为字段分隔符。如果FS
是单个字符,则字段由该字符分隔。如果FS
是空字符串,则每个单独的字符都会变成一个单独的字段。否则,FS
应该是完整的正则表达式。在特殊情况下,FS
是单个空格, 字段由空格和/或制表符和/或换行符分隔。
解决方案 4:
'[ ]+' 对我来说很管用。运行awk -W version
以获取 awk 版本。我的是GNU Awk 4.0.2
。
# cat a.txt
tcp 0 0 10.192.25.199:65002 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:26895 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:18422 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 10.192.25.199:8888 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:50010 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:50075 0.0.0.0:* LISTEN
tcp 0 0 10.192.25.199:8093 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:8670 0.0.0.0:* LISTEN
例如,我想获取 Listen 端口。因此我需要使用 awk 默认分隔符加上 ':'
# cat a.txt | awk -F '[ ]+|:' '{print $5}'
65002
26895
111
18422
22
8888
50010
50075
8093
8670
如果你只想测试默认分隔符,你可以运行
# cat a.txt | awk -F '[ ]+' '{print $4}'
10.192.25.199:65002
127.0.0.1:26895
0.0.0.0:111
0.0.0.0:18422
0.0.0.0:22
10.192.25.199:8888
0.0.0.0:50010
0.0.0.0:50075
10.192.25.199:8093
0.0.0.0:8670
结果正如预期。
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件