一尘不染

awk的默认字段分隔符

linux

很抱歉,这个愚蠢的问题已被搜索,但不确定是否找到了正确的答案,因此默认分隔符仅是awk的空间?


阅读 1081

收藏
2020-06-03

共1个答案

一尘不染

这是适用于 所有主要Awk实现*实用摘要*

  • GNU awk中(gawk) -默认awk一些 Linux发行版
  • Mawkmawk) -默认awk一些 Linux发行版(例如,早期版本的Ubuntu的crysman报道称,版本19.04现在带有 GNU awk中-见下面他的评论)
  • BSD Awk-aka BWK Awk- awk类似BSD的平台(包括OSX)上的默认设置

在Linux上,awk -W version将告诉您默认的实现awk
BSD awk中 理解awk --version(其GNU awk中理解 除了awk -W version)。

所有 这些实现的最新版本
遵循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
在内。

换行符作为字段分隔符 确实 起作用,但是:

  • when RS 设置为一个值,该值导致记录 本身 包含\n实例(例如,when RS设置为 空字符串 ;请参见下文)。
  • 通常 ,当使用该split()函数将字符串拆分为没有显式字段分隔符参数的数组元素时。
    • 即使 输入记录 不会包含\n实例(如果默认设置RS有效),该split()函数在调用时也不会在 来自不同源多行字符串 上使用显式的字段分隔符作为参数(例如,通过-voption或as 传递的变量)伪文件名) 始终 视为\n字段分隔符。

重要的非默认注意事项

  • 分配 字符串RS具有特殊的意义:它读取输入 段落模式 ,这意味着输入被分成记录 的运行 非空行 ,用 开头和结尾的忽略空行运行

  • 当你 指定的任何 其他 不是 字面 空间FS,该 解释FS 的变化从根本上

    • 单个 字符或者从指定的字符的每个字符 识别 单独 作为一个字段分隔符 -不 运行 它,与默认。
    • 例如,即使将其设置FS有效地 等于一个空格,也会将每个记录中的每个 单独的 空格实例都视为字段分隔符。[ ]
    • 要识别 运行+必须使用正则表达式量词(重复符号);例如,[\t]+将标签的 运行 识别为单个分隔符。
    • 开头和结尾的 分隔符不会被忽略,而是分隔 字段。
    • 设置FS空字符串 意味着记录的 每个 字符 都是 其自己的字段
    • 根据POSIX的要求,如果 RS 将设置为 空字符串 (段落模式),则 换行符\n也将 视为字段分隔符,而与的值无关FS

[1]不幸的是,当您使用该选项强制执行POSIX合规性()时,GNU Awk至少版本4.1.3符合关于字段分隔符的 过时
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表示帮助)。

2020-06-03