gpt4 book ai didi

awk getline() 函数不适用于空行

转载 作者:行者123 更新时间:2023-12-04 16:13:16 24 4
gpt4 key购买 nike

假设我有一个输入文件,其内容是

cat file


[source,I]

[source,more]

[source,1234]

[source,content]

首先观察两个空行,然后是一个以 [source 开头的模式,然后是从后续点开始的单个空行。我想删除后跟一个模式的一个或多个 空行(或者,删除以[source] 开头的模式上方的一个或多个空行)。我想要一个输出为

[source,I]    
[source,more]
[source,1234]
[source,content]

我制定了一个 Awk 逻辑作为

awk '!NF{getline n; if ( match(n, /^\[source/) )  {print n}}' file

除了它跳过了两个空行之后的模式并产生了一个输出之外,它工作得很好

[source,more]
[source,1234]
[source,content]

我通过打印 Awk 应该完成 match() 的行 NR 来尝试为什么 getline() 调用失败并且打印行,

awk '!NF{getline n; if ( match(n, /^\[source/) )  {print n} else {print NR}}' file
2 # Why did this fail for NR==2?
[source,more]
[source,1234]
[source,content]

想知道为什么当 getline() 应该返回 [source,I] 并打印相同内容时 NR==2 却失败了匹配正则表达式后。

$ awk --version
GNU Awk 4.1.3, API: 1.1 (GNU MPFR 3.1.4-p1, GNU MP 6.1.1)

最佳答案

如果您预先添加调试打印,您可以看到发生了什么:

$ awk '{print ">", NR, NF, $0} !NF{getline n; if ( match(n, /^\[source/) )  {print n} else {print NR}}' file
> 1 0
2
> 3 1 [source,I]
> 4 0
[source,more]
> 6 0
[source,1234]
> 8 0
[source,content]

所以 awk 读取第 1 行,它是空的,所以 !NF 是真的,所以它执行 getline 读取第 2 行,这也是空的,因为它不匹配(),而是打印当前行号为2。

现在 awk 读取第 3 行,[source,I],它是非空的,所以 !NF 是假的,所以 Action block 没有被执行,第 3 行被简单地丢弃。

现在 awk 读取第 4 行......等等。

当然,对于这样的问题,getline 无论如何都是错误的方法,一旦您修改了示例输入/输出,我们就可以向您展示如何以正确的方式做您想要的事情,但听起来这就是您想要的真正想做的是:

$ awk 'NF{if (/^\[source/) print buf $0; buf=""; next} {buf = buf $0 ORS}' file


[source,I]

[source,more]

[source,1234]

[source,content]

关于awk getline() 函数不适用于空行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42232468/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com