mkl*_*nt0 21
这是一个适用于所有主要Awk实现的实用摘要:
gawk) -默认awk在一些 Linux发行版mawk) -默认awk在一些 Linux发行版(如Ubuntu的)awk类似BSD的平台上的默认设置,包括OSX在Linux上,awk -W version将告诉您默认的实现awk.
BSD awk中仅理解awk --version(其GNU awk中理解除了对awk -W version).
所有这些实现的最新版本遵循关于字段分隔符[1] 的POSIX标准(但不是记录分隔符).
名词解释:
RS是输入记录分隔符,它描述输入如何分解为记录:
\n下面; 也就是说,输入默认分为几行.awk命令行中,RS可以指定为-v RS=<sep>.RS到一个文字,单字符的值,但GNU awk和Mawk支持多字符可以被值扩展正则表达式(BSD awk并不支持).FS是输入字段分隔符,它描述了每条记录如何分割成字段 ; 它可能是一个扩展的正则表达式.
awk命令行中,FS可以指定为-F <sep>(或-v FS=<sep>).0x20),但空间不是字面解释为(只)分离器,但有特殊的意义 ; 见下文.默认情况下:
POSIX规范.使用<blank>空格和制表符的抽象,这适用于所有语言环境,但可能包含特定语言环境中的其他字符 - 我不知道是否存在任何此类语言环境.
需要注意的是使用默认的输入记录分隔符(RS)\n,新行通常不进入图片作为字段分隔符,因为没有记录本身 包含\n在这种情况下.
然而,作为字段分隔符的换行符确实发挥作用:
RS设置为导致记录本身包含\n实例的值(例如when RS设置为空字符串 ;请参阅下文).split()函数用于将字符串拆分为数组元素而没有显式字段分隔符参数时.
\n在默认RS有效的情况下也不包含实例,但是在来自不同源split()的多行字符串上没有显式字段分隔符参数的情况下调用该函数(例如,通过-v选项传递的变量或伪文件名)始终视为\n字段分隔符.重要的非默认注意事项:
分配空字符串RS具有特殊的意义:它读取输入段落模式,这意味着输入被分成记录的运行非空行,用开头和结尾的忽略空行运行.
当你指定的任何其他不是字面空间FS,该解释FS 的变化从根本上:
FS为[ ]- 即使它实际上相当于一个空格 - 会导致每个记录中的每个单独的空间实例都被视为字段分隔符.+必须使用正则表达式量词(复制符号); 例如,[\t]+将识别标签的运行作为单个分隔符.FS为空字符串意味着记录的每个字符都是其自己的字段.RS设置为空字符串(段落模式),则newlines(\n)也被视为字段分隔符,而不管其值是多少FS.[1]遗憾的是,当您使用选项强制执行POSIX合规时,至少版本4.1.3的GNU Awk符合关于字段分隔符的过时 POSIX标准,-P(--posix):该选项生效并RS设置为非空值,换行符(\n实例)不会被识别为字段分隔符.GNU Awk手册说明了过时的行为(但忽略了提到当RS设置为空字符串时它不适用).POSIX标准在2008年发生了变化(参见注释),当有默认值时,也考虑换行字段分隔符FS- 因为GNU Awk总是没有 -P(--posix).
以下是验证上述行为2个命令:
*使用-P在效果和RS设置为空字符串,\n则仍视为字段分隔符:
gawk -P -F' ' -v RS='' '{ printf "<%s>, <%s>\n", $1, $2 }' <<< $'a\nb'
*使用-P在效果和非空 RS,\n不被视为一个字段分隔符-这是过时的行为:根据GNU Awk维护者的说法,
gawk -P -F' ' -v RS='|' '{ printf "<%s>, <%s>\n", $1, $2 }' <<< $'a\nb'
修复工作即将到来 ; 期望它在版本4.2(没有给出时间框架).
(给@JohnKugelman和@EdMorton提供帮助的帽子提示.)
Ed *_*ton 11
这个问题the default delimiter is only space for awk?很模糊,但我会尽量回答你可能会问的两个问题.
FS变量的默认值(包含告诉awk如何在读取字段时将记录分隔为字段的字段分隔符)是单个空格字符.
awk用于将记录分成字段的东西是"字段分隔符",它是一个带有一些附加功能的正则表达式,仅当字段分隔符是单个空白字符时才适用.该附加功能是:
[ ]而不是像在正则表达式中那样仅使用独立的文字空白字符.除了用于在读取输入时将记录拆分为字段的字段分隔符之外,它们还用于其他一些上下文中,例如第3个arg用于此split(),因此了解哪些上下文需要字符串或正则表达式或字段搜索以及手册页明确指出了每一个.
除其他外,上面解释了这个:
$ echo ' a b c ' | awk '{printf "%d: <%s> <%s> <%s>\n", NF, $1, $2, $3}'
3: <a> <b> <c>
$ echo ' a b c ' | awk -F' ' '{printf "%d: <%s> <%s> <%s>\n", NF, $1, $2, $3}'
3: <a> <b> <c>
$ echo ' a b c ' | awk -F'[ ]' '{printf "%d: <%s> <%s> <%s>\n", NF, $1, $2, $3}'
5: <> <a> <b>
Run Code Online (Sandbox Code Playgroud)
所以如果你不明白为什么前2个产生相同的输出但是最后的产生不同,请询问.
我们来看看GNU awk手册页:
FS- 输入字段分隔符,默认为空格.见上面的字段.
到田野部分!
在读取每个输入记录时,gawk将记录拆分为字段,使用
FS变量的值作为字段分隔符.如果FS是单个字符,则字段由该字符分隔.如果FS是空字符串,则每个单独的字符将成为单独的字段.否则,FS预计将是一个完整的正则表达式.在FS作为单个空格的特殊情况下 , 字段由空格和/或制表符和/或换行符分隔.