【问题标题】:Sed progressively for lines between two patternssed 渐进式处理两种模式之间的线条
【发布时间】:2013-12-27 10:00:46
【问题描述】:

这是我的示例代码:

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 默认执行的文件中的第一个证书。如果有是比上述更容易的选择,我全神贯注)。

【问题讨论】:

    标签: bash sed


    【解决方案1】:

    我不确定您是否可以在 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 的行范围,并使用print(又名print $0)重定向到由变量file 指定的当前文件。因此它每次都会写入相关文件。

    另外,您将如何将其更改为将内容输出到标准输出?我希望找到一种方法来指定“第 N 个”模式参数,我将从一个简单的 for 循环中提供该参数,该循环运行的次数与发现模式“BEGIN”的次数一样多。

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

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

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

    【讨论】:

    • 有趣。那行得通。你能向你的 awk 解释工作部分吗?另外,您将如何将其更改为将内容输出到标准输出?我希望找到一种方法来指定“第 N 个”模式参数,我将从一个简单的 for 循环中提供该参数,该循环运行的次数与发现模式“BEGIN”的次数一样多。
    • 太棒了,感谢您的额外解释!很好的答案。
    【解决方案2】:

    可以使用相反的方式。不打印默认值,只打印模式之间的行

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 2022-10-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-08
        • 2013-09-27
        • 1970-01-01
        • 2013-06-03
        相关资源
        最近更新 更多