awk的默认字段分隔符

时间:2015-05-22 20:52:48

标签: linux unix awk posix separator

对不起这个愚蠢的问题,搜索但不自信是找到了正确答案,所以默认分隔符只是awk的空格?

3 个答案:

答案 0 :(得分:19)

这是实用摘要,适用于所有主要的Awk实施

  • GNU Awk(gawk) - 部分 Linux发行版中的默认awk
  • Mawk mawk) - 部分 Linux发行版中的默认awk(例如,Ubuntu)
  • BSD Awk - a.k.a. BWK Awk - 类似BSD的平台上的默认awk,包括OSX

在Linux上,awk -W version会告诉您默认awk的实现方式 BSD Awk 了解awk --version(GNU Awk另外 <}>

所有这些实现的最新版本遵循{{3>}关于 field 分隔符 [1] (但不是记录分隔符)。

词汇表:

  • awk -W version input- 记录分隔符,它描述了如何将输入分解为记录

    • POSIX规定的默认值换行符,在下面也称为RS;也就是说,输入默认分为
    • \n的命令行中,awk可以指定为RS
    • POSIX将-v RS=<sep>限制为文字,单字符值,但GNU Awk和Mawk支持可能扩展的多字符值正则表达式(BSD Awk 支持)。
  • RS input- 字段分隔符,其中描述了 每条记录的方式分为字段 ;它可能是扩展正则表达式

    • FS的命令行中,awk可以指定为FS(或-F <sep>)。
    • POSIX standard 正式 空间-v FS=<sep>),但该空间不是字面解释为(唯一)分隔符,但具有特殊含义 ;见下文。

默认

  • 任何 空格 和/或 标签和/或新行被视为字段分隔符
  • 忽略前导和尾随运行

POSIX规范。 POSIX-mandated default value,对于所有区域设置都是如此,但可以在特定区域设置其他字符 - 我不知道如果存在任何此类语言环境。

请注意使用默认输入记录分隔符0x20),RS换行符通常不会输入图片作为字段分隔符,因为在这种情况下没有记录本身包含\n

作为字段分隔符的新行执行开始发挥作用,但是:

  • \n设置为导致包含RS个实例的记录本身的值时(例如\n时设置为空字符串;见下文。)
  • 通常,当RS函数用于将字符串拆分为数组元素而没有显式字段分隔符参数时。
    • 即使输入记录在默认split()生效的情况下也不包含\n个实例,但在没有调用的情况下调用RS函数来自不同来源的多行字符串的显式字段分隔符参数(例如,通过split()选项传递的变量或作为伪文件名)总是-v视为字段分隔符。

重要的非默认注意事项

  • 字符串分配给\n具有特殊含义:它以 段落模式读取输入> ,意味着 非空行 的输入会将输入分解为记录,忽略空行的前导和尾随运行

  • 当您其他文字空间分配给RS 时,对{的解释{1}} 从根本上改变

    • 单个字符或指定字符 set 中的每个字符单独识别 字段分隔符 - 不是运行,与默认值一样。
      • 例如,将FS设置为FS - 即使有效相当于一个空格 - 会导致每个个别空间实例记录被视为字段分隔符。
      • 要识别运行,必须使用正则表达式量词(复制符号)FS;例如,[ ]会将运行标签识别为单个分隔符。
    • 不会忽略前导和尾随分隔符,而是将字段分开。
    • +设置为空字符串 表示记录的每个字符 为< strong>自己的领域
  • 作为uses the abstraction <blank> for spaces and tabs,如果 [\t]+设置为空字符串 (段落模式), 换行符FS被视为字段分隔符,与RS的值无关。

[1]遗憾的是,当您使用该选项强制执行POSIX合规时,至少版本4.1.3的GNU Awk符合关于字段分隔符的过时 POSIX标准{ {1}}(\n):如果该选项生效且FS设置为非空值,则无法识别换行符(-P个实例)作为字段分隔符。 GNU Awk手册说明了过时的行为(但忽略了当--posix设置为字符串时它不适用。当RS具有默认值时,POSIX标准在2008年(见注释)更改为考虑换行符字段分隔符 - 因为GNU Awk一直在做没有 \nRS) 以下是2个验证上述行为的命令:
* FS生效,-P设置为空字符串--posix 视为字段分隔符:
-P
*如果RS生效且非空 \ngawk -P -F' ' -v RS='' '{ printf "<%s>, <%s>\n", $1, $2 }' <<< $'a\nb'不会被视为字段分隔符 - 这是过时的行为:
-P
根据GNU Awk维护者的说法,修复即将到来;期待它在版本 4.2 (没有给出时间框架) (给@JohnKugelman和@EdMorton提供帮助的帽子提示。) 功能

答案 1 :(得分:11)

问题the default delimiter is only space for awk?含糊不清,但我会尝试回答您可能会问的两个问题。

FS变量的默认值(包含告诉awk如何在记录时将记录分成字段的字段分隔符)是单个空格字符。

awk用来将记录分成字段的东西是&#34;字段分隔符&#34;这是一个带有一些附加功能的正则表达式,仅当字段分隔符是单个空白字符时才适用。其他功能是:

  1. 在字段拆分期间忽略前导和尾随空格。
  2. 字段以连续的空格字符链分隔,包括空格,制表符和换行符。
  3. 如果要将文字空白字符用作字段分隔符,则必须将其指定为[ ],而不是像在正则表达式中那样仅使用独立的文字空白字符。
  4. 除了用于在读取输入时将记录分割成字段的字段分隔符之外,它们还用于其他一些上下文中,例如, split()的第3个arg,因此了解哪些上下文需要字符串或正则表达式或fieldsep非常重要,并且手册页明确指定了每个。

    除此之外,上面解释了这个:

    $ 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>
    

    所以如果你不明白为什么前两个产生相同的输出但是最后一个输出不同,请询问。

答案 2 :(得分:8)

让我们来看看GNU awk手册页:

  

FS - 输入字段分隔符,默认为空格。请参阅上面的字段

字段部分!

  

在读取每个输入记录时,gawk使用FS变量的值作为字段分隔符将记录拆分为字段。如果FS是单个字符,则字段由该字符分隔。如果FS是空字符串,则每个单独的字符将成为单独的字段。否则,FS应该是完整的正则表达式。在FS是单个空格的特殊情况下,字段由空格和/或制表符和/或换行符分隔。