【问题标题】:PCRE regex doesn't seem to work when used from shell with grep从带有 grep 的 shell 中使用 PCRE 正则表达式似乎不起作用
【发布时间】:2024-01-19 06:01:01
【问题描述】:

我正在尝试使用传递到grep 的 PCRE 正则表达式为反编译的 DTS 文件使用捕获组输出节点。我只对key-samkey {(...)}; 节点感兴趣。

关于我可能做错了什么的任何想法,或者您能指出任何替代方法来提取节点及其内容吗?我不能使用bash=~ 运算符,因为要求我们只使用sh

我尝试了模式:

/(key-samkey {[.]*.+?[.]*};)/s

(key-samkey {[\s\S]*.+?(?=};))

我使用的确切命令是:

cat {input file} | grep -Po "{pattern}"

这两种模式似乎都可以在具有 PCRE 语法的在线正则表达式测试网站上正常工作,但在从 shell 执行时会失败。

我正在运行模式匹配的文件的结构如下:

/dts-v1/;

/ {

    signature {

        key-samkey {
            required = "conf";
            algo = "sha256,rsa4096";
            rsa,r-squared = <xxxxxxxx>;
            rsa,modulus = <xxxxxxxx>;
            rsa,exponent = <0xxx 0xxxxxx>;
            rsa,n0-inverse = <0xxxxxxxxx>;
            rsa,num-bits = <0xxxxx>;
            key-name-hint = "samkey";
        };
    };
};

【问题讨论】:

  • grep 是一个面向行的工具。改用适当的解析器
  • 你可以试试(虽然不安全)grep -Poz 'key-samkey\s*{[^{}]*}' file。见ideone.com/5VbWqZ
  • 为什么投反对票?如果您认为它可以以比grep 更好的方式完成,请解释。它始终是一个带有单个节点的简单文件,并在一个 shell 脚本中使用,该脚本可以自动执行迄今为止手工完成的操作。我认为进行“正确”解析对于这项任务来说是多余的。

标签: regex linux grep sh


【解决方案1】:

用 sed 定义一系列行更简单:

sed -n '/key-samkey {/,/};/p' file

【讨论】:

    【解决方案2】:

    你快到了。您可以使用的正则表达式是

    (?s)(key-samkey \{.+?\};).

    • (?s):点. 匹配所有内容(DOTALL)
    • \{\}:您必须避开这些,因为它们在正则表达式中具有特殊含义。
    • .+?:匹配它可以非贪婪的所有内容,这意味着,在这种情况下,所有内容直到第一个 };

    然后使用 grep 的 -z 开关,这会将输入中的换行符替换为空字节,以便 grep 将输入视为一大行。

    示例:我将您的示例存储在文件test.file

    > grep -Pzo '(?s)(key-samkey \{.+?\};)' test.file
    
    key-samkey {
                required = "conf";
                algo = "sha256,rsa4096";
                rsa,r-squared = <xxxxxxxx>;
                rsa,modulus = <xxxxxxxx>;
                rsa,exponent = <0xxx 0xxxxxx>;
                rsa,n0-inverse = <0xxxxxxxxx>;
                rsa,num-bits = <0xxxxx>;
                key-name-hint = "samkey";
            };
    

    【讨论】:

    • 关于转义大括号:右大括号根本不是特殊字符(如右方括号)。左大括号是一个特殊字符,但是对于某些正则表达式引擎(包括 PCRE),您可以在不存在混淆风险的情况下省略转义(使用量词 {m,n}{n})。
    • @CasimiretHippolyte 是的,但是您编写 regexen 不仅要执行,而且要在一周内由您自己和其他人阅读,转义不在 [] 中的特殊字符使其成为可能无需在脑海中进一步解析,就清楚如何阅读它们。
    【解决方案3】:

    所提供的答案将为您解决问题。但是,如果您不想更改正则表达式,我找到了一种方便的方法来执行 PCRE 表达式而不会痛苦。您可以尝试使用 Sublime(MAC 中的 COMMAND+F)打开您的 DTS 文件,确保 Regular expression 选项已打开,然后粘贴您的表达式(我刚刚尝试过您的示例)。点击“查找全部”并复制结果。

    【讨论】:

      最近更新 更多