使用 awk 在匹配模式后提取内容时出错

使用 awk 在匹配模式后提取内容时出错

我想用来awk将输入文件的内容排序到不同的输出文件中。

简单的例子

假设有以下输入文件:

  • $cat sample.txt
    START  
    Unix  
    Linux  
    START  
    Solaris  
    Aix  
    SCO  
    

awk程序

awk '/START/{x="F"++i;}{print > x}' sample.txt

将以下输出生成到文件中:

  • $ cat F1
    START  
    Unix  
    Linux  
    
  • $ cat F2
    START  
    Solaris  
    Aix  
    SCO  
    

实际使用场景

当我将这种技术应用到我的实际用例中时,

awk '/Certificate Revocation List (CRL):/{x="F"++i;}{print > x}' test_cert.pem

不提取从以下位置开始的内容Certificate Revocation List (CRL):

相反,它给出以下错误:

awk: cmd. line:1: (FILENAME=test_cert.pem FNR=1) fatal: expression for `>' redirection has null string value

我尝试将模式放在引号中,但它不起作用,不确定模式是否是多字的,我们如何提取内容。

外观test_cert.pem如下:


Certificate Revocation List (CRL):
        Version 2 (0x1)
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = XX, O = XXXXX, OU = 0003 374154744412350, CN = XXX
        Last Update: Aug 15 04:37:16 2021 GMT
        Next Update: Sep 23 03:47:16 2021 GMT
        CRL extensions:
            X509v3 CRL Number:
                209
            X509v3 Authority Key Identifier:
                keyid:09:DF:3B:15:GE:10:08:D5:86:8F:5B:E7:E6:36:B9:A1:A8:1A:83:18

Revoked Certificates:
    Serial Number: AAS60F19DABCDA8AGHIK3E4A59988AAFDA8E6
        Revocation Date: Jan 29 12:45:09 2021 GMT
    Serial Number: GGF0HHHABCDA8AGHIK3E4A599KKKAFDA8E6
        Revocation Date: Jul 25 4:32:24 2021 GMT
    Signature Algorithm: sha256WithRSAEncryption
         1e:cc:8e:9d:gv:ae:eb:0a:67:95:4b:8b:b6:5d:9e:bd:48:42:
         a5:25:e8:eb:b2:22:BV:42
-----BEGIN X509 CRL-----
MIIDLLKKARMCAQEwLLKKAOKONcNAQELBQYYUzvgfzELLLKKA1UEBhMCRlIxDzANBgNV
mZ7YI0YYUzvgrzYYUzvgz9Deb78UGbaedXkYYUzvgr5Hu1Zm16YYUzvgXo67IiNUI=
-----END X509 CRL-----

答案1

您的情况有两个问题。

第一个问题是您的匹配模式包含正则表达式特有的字符,在本例中为( ... ).您需要转义它们才能让您的程序真正找到匹配项。目前,您的程序找不到匹配项,因此x从未初始化。这就是“重定向具有空字符串值”错误的原因。

此外,即使正则表达式的表述正确,对于任何出现的情况都会失败字符串的第一次出现Certificate Revocation List (CRL):。所以你需要

  1. 更正你的正则表达式
  2. 确保除非x初始化,否则不会打印任何内容。

你可以将你的程序更改为

awk '/Certificate Revocation List \(CRL\):/{x="F"++i;}{if (x) print > x}' test_cert.pem

它会再次起作用。

这又是一个例子为什么如果您只是查找固定字符串,则不应使用正则表达式匹配。要强化您的程序以解决此类问题,请使用

awk '$0=="Certificate Revocation List (CRL):"{x="F"++i}{if (x) print >x}' test_cert.pem

反而。

答案2

输入文件顶部有一个空行。当awk代码读取此内容时,该x变量没有值,因此print >x执行时会触发错误。

这是由于awk代码期待要在第一行匹配的正则表达式,以便x将其设置为某个值。

您可以通过在块F0中启动 x 来解决此问题BEGIN

awk 'BEGIN { x = "F0" } /...your RE.../ { x = "F" ++i }  { print >x }' file

这将产生将正则表达式第一个匹配之前的所有行输出到文件的效果F0

您可能还想丢弃x设置之前读取的任何内容:

awk '/...your RE.../ { x = "F" ++i } x != "" { print >x }' file

此外,正则表达式需要对其括号进行转义,因为它们很特殊:

awk '/Certificate Revocation List \(CRL\):/ { x = "F" ++i } x != "" { print > x }' 

相关内容