AWK 是否具有与 SED 类似的能力,可以根据行中的文本而不是行号来查找行范围?

AWK 是否具有与 SED 类似的能力,可以根据行中的文本而不是行号来查找行范围?

解决方案:文件是用 CR 而不是 LF 换行符保存的。 Mosvy指出了这一点,但只是作为评论发布,而不是答案,所以我无法正式感谢他帮助我找到原因并解决问题。

谢谢 mosvy,如果你回来请发表答案,这样我就可以给你竖起大拇指。

SED 似乎有:

sed '3,10d;/<ACROSS>/,$d' input.txt > output.txt

(删除第 3-10 行,然后从包含“<ACROSS>”的行删除到文件末尾;然后写出输出。)

即使我只尝试:

sed '3,10d' input.txt > output.txt

但由于某种原因,这两种方法似乎都无法在我的 Mac 上运行。

不知道还能尝试什么。

我希望 AWK 有一些非常相似的东西。

更新:

当我输入:

sed '3,10d' input.txt > output.txt

它不会删除第 3 - 10 行;它只是将整个文件返回到output.txt;

当我尝试时:

sed '/<ACROSS>/,$d' input.txt > output.txt

输出.txt 为空

另外,我是10.9.4

** 更新 2:

谢谢莫维!!我希望我能对你的评论投赞成票。这是问题的解决者。

事实证明文件是用 CR 而不是 LF 换行符保存的

当我转换它时,一切都解决了。

感谢所有做出贡献的人。

答案1

/usr/bin/sed '3,10d'在我的 Mac (Mojave) 上运行得非常好。即便如此,使用 awk:

awk '(NR >= 3) && (NR <= 10) {next} /<ACROSS>/{exit} 1'

...如果行号在 3 到 10 之间,则跳过行,并在到达带有 的行时退出<ACROSS>(并打印其他所有内容)。

答案2

你的 sed 工作正常。即便如此,在 Awk 中还是有, --“Between”运算符。以下是一些示例(默认操作 = 打印)

打印“开始”和“停止”之间的行

awk '/start/,/stop/'

3号线和10号线之间的线路

awk 'NR==3, NR==10'

<ACROSS>和结束之间的线

awk '/<ACROSS>/, 0'

(0为假,所以永远不会结束)

答案3

OP的问题是由文件文件使用CR\r/ ascii 13)而不是LF\n/ ascii 10)作为行终止符引起的,正如预期的那样sed。 usingCR是经典 MacOS 中使用的约定;作为一个非 Mac 用户,在过去的二十年中我在野外遇到的唯一用途是在 PDF 文件中,它使任何用 编写的简单 PDF 解析器变得非常复杂perl(与RSinmawk和不同gawk$/inperl不能是正则表达式) 。


至于标题中的问题,是的,awk支持范围模式,并且您可以在其中自由混合正则表达式和行号谓词(或任何表达式)。例如:

NR==1,/rex/   # all lines from the 1rst up to (and including)
          # the one matching /rex/

/rex/,0   # from the line matching /rex/ up to the end-of-file.

awk的范围与 的范围不同sed,因为awk最后谓词也可以匹配开始范围的行。sed的行为可以通过以下方式模拟:

s=/start/, !s && /last/ { s = 0; print }

然而, in 的范围awk仍然相当有限,因为它们不是真正的表达式(它们不能被否定,不能成为其他表达式的一部分,不能用于if(...)等)。另外,这并不神奇:如果你想用“上下文”来表达类似范围的东西(例如/start/-4,/end/+4),你将不得不滚动你自己的循环缓冲区和额外的逻辑。

相关内容