GNU Awk 4.2 中 FS = " " 的行为是什么?

2024-03-03

The first week of October, Arnold Robbins announced Beta release of gawk 4.2.0 now available in the GNU-announce, bug-gawk and comp.lang.awk https://groups.google.com/forum/#!topic/comp.lang.awk/UnoZTItfiko mailing lists. It is available in http://www.skeeve.com/gawk/gawk-4.1.65.tar.gz http://www.skeeve.com/gawk/gawk-4.1.65.tar.gz 1 and he mentions that This is a major release, with many significant new features.

因此,我浏览了 NEWS 文件来深入研究这些功能,并在此时停下来进行一些测试:

从 4.1.4 到 4.2.0 的变化

...

  1. POSIX 标准的修订删除了 POSIX 的特殊情况 当 FS = " " 时的模式,其中换行符不是字段分隔符。代码 和文档已更新。

如果我理解正确的话,他谈论的是GNU Awk 用户指南 → 4.5.2 使用正则表达式分隔字段 https://www.gnu.org/software/gawk/manual/html_node/Regexp-Field-Splitting.html:

'FS = " "'(单个空格)和 'FS = "[ \t\n]+"'(匹配一个或多个空格、制表符或换行符的正则表达式)这两种情况之间存在重要区别。对于 FS 的两个值,字段由空格、制表符和/或换行符的运行(多个相邻出现)分隔。然而,当 FS 的值为“”时,awk 首先从记录中去除前导和尾随空白,然后决定字段的位置。

也就是说,使用之间的区别FS = " " and FS = "[ \t\n]+".

我运行了新版本并进行了测试--posix https://www.gnu.org/software/gawk/manual/html_node/Options.html mode:

$ ./gawk --posix -F" " '{print "NR:", NR; for(i=1;i<=NF;i++) print i, $i}' <<< "hello how are
you"
NR: 1
1 hello
2 how
3 are
NR: 2
1 you

和我之前的 awk (4.1.3) 相比并看不出有什么区别:

$ gawk --posix -F" " '{print "NR:", NR; for(i=1;i<=NF;i++) print i, $i}' <<< "hello how are
you"
NR: 1
1 hello
2 how
3 are
NR: 2
1 you

总而言之,我的问题是:行为有什么不同FS = " " in the --posixGNU Awk 4.2 的模式?具体改变了什么?

1 yes, I also thought it should be 4.2.tar.gz, but http://www.skeeve.com/gawk/gawk-4.2.tar.gz http://www.skeeve.com/gawk/gawk-4.2.tar.gz does not exist


它是 4.2 的测试版,因此它是根据 4.1 构建/命名的。当它正式发布时,它将是 4.2.tar.gz。

我没有方便的 4.2 beta 来测试以下理论,但这是我认为关于默认值的公告FS=" " means:

以前在 POSIX 中设置时FS=" "这意味着字段由所有空白字符分隔除了换行符。另一方面,gawk 默认将换行符作为分隔符之一,并且您必须添加 --posix 才能获得 POSIX 行为。看:

$ gawk --version
GNU Awk 4.1.4, API: 1.1 (GNU MPFR 3.1.5, GNU MP 6.1.2)

$ printf 'a b\nc' | awk -v RS='^$' 'NR==1{for (i=1; i<=NF;i++) print NR, NF, i, "<" $i ">"}'
1 3 1 <a>
1 3 2 <b>
1 3 3 <c>

$ printf 'a b\nc' | awk --posix -v RS='^$' 'NR==1{for (i=1; i<=NF;i++) print NR, NF, i, "<" $i ">"}'
1 2 1 <a>
1 2 2 <b
c>

显然现在 POSIX 标准已经更新为包括\n在分隔符集中,当FS=" "因此,gawk 不再需要在 posix 与非 posix 模式下在这方面表现不同,而是所有 POSIX awks 都需要更新为 gawk 默认情况下的行为。

您问题中的示例没有测试这一点,因为它正在使用\n作为RS(默认),因此无法测试当\n是在一个记录之内。设置后再次尝试RS="^$".

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

GNU Awk 4.2 中 FS = " " 的行为是什么? 的相关文章

  • 执行 tail -F 直到匹配模式

    我想做一个tail F在文件上直到匹配模式 我找到了一种使用方法awk 但恕我直言 我的命令并不是很干净 问题是我need由于某些限制 只能用一行来完成 tail n 0 F tmp foo awk W interactive if 1 E
  • 使用 awk(或熟悉的)将多行合并为 1 行

    我需要将 nmap 输出中的多行合并为一行 FROM Nmap scan report for example com 22 tcp open ssh 80 tcp open http 111 tcp open rpcbind 1720 t
  • grep 匹配的行和字符串位置

    我需要找到一种方法将 grep 匹配的精确坐标从一个文件输出到另一个文件 所以说 模式 包含要匹配的字符串模式列表 搜索 是一个基于行的文本 ASCII 文件 其中包含要搜索的文本 with grep onf patterns search
  • 如何在 Bash shell 脚本中检查目录是否存在?

    什么命令检查 Bash shell 脚本中的目录是否存在 检查目录是否存在 if d DIRECTORY then echo DIRECTORY does exist fi 检查目录是否不存在 if d DIRECTORY then ech
  • awk 有条件地组合多行

    我想将多行不同长度的值合并到一行 如果它们与 ID 匹配 输入示例是 ID Value a 1 49 a 2 75 b 1 120 b 2 150 b 3 211 c 1 289 d 1 301 d 2 322 所需的输出示例是 ID Va
  • 将标准输出重定向到文件

    我正在尝试执行相当于 bash 命令的操作ls gt foo txt in C 下面的代码将输出重定向到变量 include
  • SED 或 AWK 将所有内容替换为另一个文件中的模式

    我正在尝试使用 SED 脚本进行模式替换 但它无法正常工作 样本内容 txt 288Y2RZDBPX1000000001dhana JP2F64EI1000000002d EU9V3IXI1000000003dfg1000000001dfd
  • 正则表达式用 SED/AWK 替换特定列

    我的数据如下所示 制表符分隔 Organ K ClustNo Analysis LN K200 C12 Gene Ontology LN K200 C116 Gene Ontology CN K200 C2 Gene Ontology 我想
  • 比较 timespec 值

    比较两个 timespec 值以查看哪个先发生的最佳方法是什么 下面这句话有什么问题吗 bool BThenA timespec a timespec b Returns true if b happened first b will be
  • 使用 awk 添加列。这个 awk 命令有什么问题?

    我想将两列添加到大约 10 000 列的文件中 我想在每行插入 nr 22 作为第一列 然后我想要将原始第一列作为第二列 然后作为第三列我想要插入第 nr NR 行 之后我想要打印其余的原始列 我想我可以用下面的 awk 行来做到这一点 a
  • 使用 grep 仅打印上下文

    Using grep http www computerhope com unix ugrep htm 您可以打印与您的搜索查询匹配的行 添加一个 C选项将打印两行周围的上下文 如下所示 gt grep C 2 lorem some con
  • unix下C++递归复制目录

    没有任何可供使用的功能示例c without additional libs将递归文件和文件夹复制到新位置 一些替代方案system cp R f dir call 我只找到这个C 中的递归目录复制 https stackoverflow
  • POSIX:FreeBSD 与 Linux 中的管道系统调用

    在 Linux 2 6 35 22 generic 中 man pipe指出 pipeline 创建一个管道 一个可用于进程间通信的单向数据通道 在 FreeBSD 6 3 RELEASE p5 中 man pipe指出 pipeline
  • 创建带小数秒的时间戳

    awk可以使用 strftime 函数生成时间戳 例如 awk BEGIN print strftime Y m d H M S 2019 03 26 08 50 42 但我需要一个带有小数秒的时间戳 最好是纳秒 gnu date可以用 N
  • 将文本文件转换为逗号分隔的字符串

    我似乎没有找到与这个问题完全匹配的问题 我有一个文本文件 每行有一个文本标记 没有任何逗号 制表符或引号 我想根据文件内容创建一个逗号分隔的字符串 Input one two three Output one two three 我正在使用
  • getline() 与 fgets():控制内存分配

    要从文件中读取行 有getline and fgets POSIX 函数 忽略可怕的gets 这是常识getline 优先于fgets 因为它根据需要分配行缓冲区 我的问题是 这不危险吗 如果有人意外或恶意地创建了一个 100GB 的文件
  • 从命名管道读取

    我必须实现一个 打印服务器 我有 1 个客户端文件和 1 个服务器文件 include
  • 将年月(“yyyy-mm”格式)转换为日期?

    我有一个如下所示的数据集 Month count 2009 01 12 2009 02 310 2009 03 2379 2009 04 234 2009 05 14 2009 08 1 2009 09 34 2009 10 2386 我想
  • 如何在 mac 中使用“getopt”命令让 bash 处理长参数?

    我想让我的 bash 脚本处理长参数 我发现getopt 但 OS X 不支持它 谁能告诉我为什么getoptBSD 实现了 GNU 没有实现 我尝试构建getopt在 GNU C lib 中 但由于我对 Linux 的技能不佳而失败了 有
  • 如何从标准输入读取一行,阻塞直到找到换行符?

    我试图从命令行的标准输入一次读取任意长度的一行 我不确定是否能够包含 GNU readline 并且更喜欢使用库函数 我读过的文档表明getline应该可以工作 但在我的实验中它不会阻塞 我的示例程序 include

随机推荐