繁体   English   中英

对两种模式之间的线条逐渐进行Sed

[英]Sed progressively for lines between two patterns

这是我的示例代码:

BEGIN
one
one
one one
one
END
filler filler filler filler
BEGIN
two two
two
two two
END
filler filler filler filler
BEGIN
three three three
three three
three
END

我想提取(和包括) BEGINEND之间的线。 我有一个已经这样做的sed:

sed '/BEGIN/,/END/!d' file

但我想逐步提取模式空间。 也就是说,我可以对上面的sed命令做什么才能输出第一个块? 然后第二块? 第三个? 等等...

(正如你们中的一些人可能猜到的那样,我的最终目标是使用x509证书解析文件并提取文件中每个证书的数据,而不仅仅是openssl默认执行的文件中的第一个证书。如果有更简单的话除了以上之外,我都是耳朵)。

我不确定你能在sed轻松做到这一点,但你可以用awk

awk '/^BEGIN$/         { file = sprintf("file%d.out", ++i); }
     /^BEGIN$/,/^END$/ { print > file }' data

这会为第一个块生成file1.out ,为第二个块生成file2.out等。


你能解释一下awk的工作部件吗?

第一个规则行匹配包含BEGIN行,并使用变量i的计数器在变量file生成文件名(预先递增,因此第一个文件是file1.out )。

第二个规则行匹配从BEGINEND的行范围,并使用重定向到变量file指定的当前文件的print (aka print $0 )。 因此,它每次都写入相关文件。

另外,如何将其更改为输出内容到stdout? 我希望有一种方法可以指定一个“第N个”模式参数,我将从一个简单的for循环中提供该参数,该循环运行的次数与发现模式“BEGIN”的总数相同。

您可以通过使用一行来计算块并跳过除相关块之外的所有块,然后只打印相关块的数据。

awk -v N=$N '/^BEGIN$/         { if (++i != N) next; }
             /^BEGIN$/,/^END$/ { print }' data

-v N=$N将shell变量$N中继到awk ; 第一行计数(使用i部分,跳过除第N 以外的所有部分。第二行仅在第一行不跳过时触发,因此它打印第N 块的内容。一些awk afficionados(可能是APL程序员在业余时间)会省略{ print }块,但我认为它使代码更清晰,其他人必须维护代码。

可以使用相反的方式。 不打印默认值并仅打印图案之间的线条

sed -n '/BEGIN/,/END/p' <file

使用awk,只导出第二条记录,不需要遍历整个文件。 您将在文件“file.out”中获得结果。 您可以自己定义数字(n = 2)。

n=2
awk -v N=$n '/^BEGIN$/{++i}
     /^BEGIN$/,/^END$/ { if (i==N) {print > "file.out";quit}}'  file

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM