awk的默认字段分隔符

对不起,这个愚蠢的问题,search但没有信心是正确的答案被发现,所以默认分隔符只是空间为awk

Solutions Collecting From Web of "awk的默认字段分隔符"

这是一个实用的总结 ,适用于所有主要的Awk实现

  • GNU Awk( gawk ) – 某些 Linux发行版中的默认awk
  • Mawkmawk ) – 在某些 Linux发行版中的默认awk (例如Ubuntu)
  • BSD Awk – 又名BWK Awk – BSD类平台(包括OSX)上的默认awk

在Linux上, awk -W version会告诉你哪个实现是默认的awk
BSD Awk 理解awk --version除了 awk -W version ,GNU awk 还能理解)。

所有这些实现的最新版本遵循POSIX关于字段分隔符 [1]的标准 (但不记录分隔符)。

名词解释:

  • RS输入记录分隔符 ,它描述输入如何分解为记录

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

    • awk的命令行上, FS可以被指定为-F <sep> (或-v FS=<sep> )。
    • POSIX规定的默认值在形式上是一个空格0x20 ),但是该空格不是从字面上解释为(唯一的)分隔符,而是具有特殊含义 ; 见下文。

默认情况下

  • 任何运行空格 和/或 制表符和/或换行符都被视为字段分隔符
  • 前导和尾随运行被忽略

POSIX规范。 使用空格和制表符的抽象<blank> ,对于所有语言环境都是如此,但可以在特定语言环境中包含其他字符 – 我不知道是否存在任何这样的语言环境。

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

换句话说,作为现场分离器的换行器起作用

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

重要非默认注意事项

  • 字符串分配给RS具有特殊含义 :它以段落模式读取输入,这意味着输入通过非空行运行分解成记录, 忽略空行的前导和尾随运行

  • 当您将除文字空间以外的任何内容指定给FSFS解释FS 根本上改变

    • 来自指定字符单个字符或每个字符 单独识别为字段分隔符 – 不运行它,如默认值一样。
      • 例如,将FS设置为[ ] – 即使它实际上相当于一个空格 – 也会将每个记录中的每个单独的空间实例视为字段分隔符。
      • 要识别运行 ,必须使用正则表达式量词(复制符号) + ; 例如, [\t]+会将选项卡的运行识别为单个分隔符。
    • 前导分隔符和尾随分隔符不会被忽略 ,而是将字段分开。
    • FS设置为空字符串意味着记录的每个字符都是它自己的字段
  • 按照POSIX的规定 ,如果RS被设置为空字符串 (段落模式), 换行符\n被视为字段分隔符 ,而不考虑FS的值。

[1]不幸的是,GNU Awk至少达到版本4.1.3,当您使用该选项来强制执行POSIX合规性时,符合现场分隔符的过时 POSIX标准, -P (– --posix ):使用该选项生效RS设置为非空值,换行( \n实例)不被识别为字段分隔符。 GNU Awk手册阐明了过时的行为(但是忽略提及当RS设置为字符串时不适用)。 2008年POSIX标准发生了变化(见注释),当FS有默认值时考虑换行字段分隔符,因为GNU Awk一直没有使用 -P (– --posix )。
以下是验证上述行为的两个命令:
*如果-P有效且RS设置为空字符串 ,则\n 仍然被视为字段分隔符:
gawk -P -F' ' -v RS='' '{ printf "<%s>, <%s>\n", $1, $2 }' <<< $'a\nb'
*使用-P非空 RS\n不被视为字段分隔符 – 这是过时的行为:
gawk -P -F' ' -v RS='|' '{ printf "<%s>, <%s>\n", $1, $2 }' <<< $'a\nb'
根据GNU Awk维护人员的说法, 即将出现的一个问题是 期待它在4.2版本(没有时间框架给出)。
(提示@JohnKugelman和@EdMorton的帮助。)

这个问题the default delimiter is only space for awk? 是模棱两可的,但我会尽量回答你可能会问的两个问题。

FS变量的默认值(包含字段分隔符,告诉awk如何将记录分隔到字段中),它是一个单独的空格字符。

awk用于将记录分隔到字段的东西是一个“字段分隔符”,它是一个正则表达式,它带有一些额外的功能,仅当字段分隔符是单个空字符时才适用。 附加功能是:

  1. 领域和拖尾的白色空间在字段拆分过程中被忽略。
  2. 字段在包含空格,制表符和换行符的连续空格字符链中分隔。
  3. 如果你想使用空白字符作为字段分隔符,你必须指定它为[ ]而不是像在正则表达式中那样只是一个独立的文字空白字符。

除了字段分隔符用于在输入读取时将记录拆分为字段以外,还可以在其他一些情况下使用字段分隔符,例如split()的第三个参数,因此了解哪些上下文需要字符串或正则表达式很重要,或者一个fieldsep和man页面清楚地指定了每一个。

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

 $ echo ' abc ' | awk '{printf "%d: <%s> <%s> <%s>\n", NF, $1, $2, $3}' 3: <a> <b> <c> $ echo ' abc ' | awk -F' ' '{printf "%d: <%s> <%s> <%s>\n", NF, $1, $2, $3}' 3: <a> <b> <c> $ echo ' abc ' | awk -F'[ ]' '{printf "%d: <%s> <%s> <%s>\n", NF, $1, $2, $3}' 5: <> <a> <b> 

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

我们来看看GNU awk手册页:

FS – 输入字段分隔符,默认为空格。 见上面的字段

字段部分!

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