REGEX:不匹配 - 请检查我的解决方案



我正在做的是尝试使用diff--ignore-matching-lines=来忽略包含某些模式的行。原因是我有一个BASH脚本,该脚本使用HPE的RESTFUL API检查主机上的BIOS设置。当两种正则匹配主机上的BIOS设置以及我存储在变量中的设置上时,我使用--ignore-matching-lines=省略了BIOS设置中的模式。如果diff发现设置与"黄金配置"不匹配,则显示终端上的差异并提示应用正确的配置。我正在使用的设置是UEFI引导订单和Intel SGX设置。

这个特定的正则问题是围绕SGX设置。HPE偶尔将时代设置为所有0的默认值。我需要确保sgxepoch值不是全部0,而是一个随机的32个字符串,如以下实例,或者我们在确保飞地分泌方面有问题。

破碎:

"SgxEpoch": "00000000000000000000000000000000"

好:

"SgxEpoch": "5FSQUWEED6XPC8PJ2CWZGQIS4WWKLKUI"

我做了很多看,发现WiktorStribiêEw在展示如何使用Posix来表明"匹配"以外的"除了"(我发现Diff不支持LookAheads(非常有帮助除了

所以我想到了以下版本,它也寻找"SgxEpoch": "",因为这就是我的比较模板的定义-https://regex101.com/r/upd1kl/1

SgxEpochRegEx='"SgxEpoch":s*("([^0].{31}|.[^0].{30}|.{2}[^0].{29}|.{3}[^0].{28}|.{4}[^0].{27}|.{5}[^0].{26}|.{6}[^0].{25}|.{7}[^0].{24}|.{8}[^0].{23}|.{9}[^0].{22}|.{10}[^0].{21}|.{11}[^0].{20}|.{12}[^0].{19}|.{13}[^0].{18}|.{14}[^0].{17}|.{15}[^0].{16}|.{16}[^0].{15}|.{17}[^0].{14}|.{18}[^0].{13}|.{19}[^0].{12}|.{20}[^0].{11}|.{21}[^0].{10}|.{22}[^0].{9}|.{23}[^0].{8}|.{24}[^0].{7}|.{25}[^0].{6}|.{26}[^0].{5}|.{27}[^0].{4}|.{28}[^0].{3}|.{29}[^0].{2}|.{30}[^0].|.{31}[^0])"|"")'

然后将其转换为BRE,因此可以与diff一起使用:

SgxEpochRegEx='"SgxEpoch":s*("([^0].{31}|.[^0].{30}|.{2}[^0].{29}|.{3}[^0].{28}|.{4}[^0].{27}|.{5}[^0].{26}|.{6}[^0].{25}|.{7}[^0].{24}|.{8}[^0].{23}|.{9}[^0].{22}|.{10}[^0].{21}|.{11}[^0].{20}|.{12}[^0].{19}|.{13}[^0].{18}|.{14}[^0].{17}|.{15}[^0].{16}|.{16}[^0].{15}|.{17}[^0].{14}|.{18}[^0].{13}|.{19}[^0].{12}|.{20}[^0].{11}|.{21}[^0].{10}|.{22}[^0].{9}|.{23}[^0].{8}|.{24}[^0].{7}|.{25}[^0].{6}|.{26}[^0].{5}|.{27}[^0].{4}|.{28}[^0].{3}|.{29}[^0].{2}|.{30}[^0].|.{31}[^0])"|"")'

这是BRE版本捕获时代的非零或空白版本的示例,也没有捕获某物。

[~]$ echo '"SgxEpoch": "5FSQUWEED6XPC8PJ2CWZGQIS4WWKLKUI"' | grep '"SgxEpoch":s*("([^0].{31}|.[^0].{30}|.{2}[^0].{29}|.{3}[^0].{28}|.{4}[^0].{27}|.{5}[^0].{26}|.{6}[^0].{25}|.{7}[^0].{24}|.{8}[^0].{23}|.{9}[^0].{22}|.{10}[^0].{21}|.{11}[^0].{20}|.{12}[^0].{19}|.{13}[^0].{18}|.{14}[^0].{17}|.{15}[^0].{16}|.{16}[^0].{15}|.{17}[^0].{14}|.{18}[^0].{13}|.{19}[^0].{12}|.{20}[^0].{11}|.{21}[^0].{10}|.{22}[^0].{9}|.{23}[^0].{8}|.{24}[^0].{7}|.{25}[^0].{6}|.{26}[^0].{5}|.{27}[^0].{4}|.{28}[^0].{3}|.{29}[^0].{2}|.{30}[^0].|.{31}[^0])"|"")'
"SgxEpoch": "5FSQUWEED6XPC8PJ2CWZGQIS4WWKLKUI"
[~]$ echo '"SgxEpoch": ""' | grep '"SgxEpoch":s*("([^0].{31}|.[^0].{30}|.{2}[^0].{29}|.{3}[^0].{28}|.{4}[^0].{27}|.{5}[^0].{26}|.{6}[^0].{25}|.{7}[^0].{24}|.{8}[^0].{23}|.{9}[^0].{22}|.{10}[^0].{21}|.{11}[^0].{20}|.{12}[^0].{19}|.{13}[^0].{18}|.{14}[^0].{17}|.{15}[^0].{16}|.{16}[^0].{15}|.{17}[^0].{14}|.{18}[^0].{13}|.{19}[^0].{12}|.{20}[^0].{11}|.{21}[^0].{10}|.{22}[^0].{9}|.{23}[^0].{8}|.{24}[^0].{7}|.{25}[^0].{6}|.{26}[^0].{5}|.{27}[^0].{4}|.{28}[^0].{3}|.{29}[^0].{2}|.{30}[^0].|.{31}[^0])"|"")'
"SgxEpoch": ""
[~]$ echo '"SgxEpoch": "00000000000000010000000000000000"' | grep '"SgxEpoch":s*("([^0].{31}|.[^0].{30}|.{2}[^0].{29}|.{3}[^0].{28}|.{4}[^0].{27}|.{5}[^0].{26}|.{6}[^0].{25}|.{7}[^0].{24}|.{8}[^0].{23}|.{9}[^0].{22}|.{10}[^0].{21}|.{11}[^0].{20}|.{12}[^0].{19}|.{13}[^0].{18}|.{14}[^0].{17}|.{15}[^0].{16}|.{16}[^0].{15}|.{17}[^0].{14}|.{18}[^0].{13}|.{19}[^0].{12}|.{20}[^0].{11}|.{21}[^0].{10}|.{22}[^0].{9}|.{23}[^0].{8}|.{24}[^0].{7}|.{25}[^0].{6}|.{26}[^0].{5}|.{27}[^0].{4}|.{28}[^0].{3}|.{29}[^0].{2}|.{30}[^0].|.{31}[^0])"|"")'
"SgxEpoch": "00000000000000010000000000000000"
[~]$ echo '"SgxEpoch": "00000000000000000000000000000000"' | grep '"SgxEpoch":s*("([^0].{31}|.[^0].{30}|.{2}[^0].{29}|.{3}[^0].{28}|.{4}[^0].{27}|.{5}[^0].{26}|.{6}[^0].{25}|.{7}[^0].{24}|.{8}[^0].{23}|.{9}[^0].{22}|.{10}[^0].{21}|.{11}[^0].{20}|.{12}[^0].{19}|.{13}[^0].{18}|.{14}[^0].{17}|.{15}[^0].{16}|.{16}[^0].{15}|.{17}[^0].{14}|.{18}[^0].{13}|.{19}[^0].{12}|.{20}[^0].{11}|.{21}[^0].{10}|.{22}[^0].{9}|.{23}[^0].{8}|.{24}[^0].{7}|.{25}[^0].{6}|.{26}[^0].{5}|.{27}[^0].{4}|.{28}[^0].{3}|.{29}[^0].{2}|.{30}[^0].|.{31}[^0])"|"")'
[~]$

我遇到的问题是我不明白上述正则是如何工作的。在我看来,这只是使用meta-character |的一堆替代方案,我基本上是在说x数字是"除newline之外的任何字符"(通过 .{x}(,然后再说一个 0,然后再进行x数字x除newline以外的任何字符(通过.{x}(。在我看来,这条正则应与以下示例相匹配,但这不...我不明白为什么。

"SgxEpoch": "00000000000000010000000000000000"
"SgxEpoch": "00000000000000000000000001000000"
"SgxEpoch": "00000100000000000000000000000000"

这里的工作与BASH脚本中的实现方式非常相似。在第一个输入fd<(curl ...(中,它以JSON格式从主机中拉出所有BIOS设置。对于第二fd<(回声...(,我以通用形式与所需的BIOS设置相呼应一个变量。然后两者都被馈送到 | python -m json.tool | perl -00pe 's:[.*?]:($x=$&)=~s/s//gs;$x:ges',以将两个输入标准化为diff,漂亮的打印格式,以通过n将JSON设置分开,因此--suppress-common-lines仅显示差异到用户,并且Perl删除了数组类型变量的 n字符跨新线作为"一个块",诸如.之类的东西。

[awilk00@nvdejb-dc-2p ~]$ SgxEpochRegEx='"SgxEpoch":s*("([^0].{31}|.[^0].{30}|.{2}[^0].{29}|.{3}[^0].{28}|.{4}[^0].{27}|.{5}[^0].{26}|.{6}[^0].{25}|.{7}[^0].{24}|.{8}[^0].{23}|.{9}[^0].{22}|.{10}[^0].{21}|.{11}[^0].{20}|.{12}[^0].{19}|.{13}[^0].{18}|.{14}[^0].{17}|.{15}[^0].{16}|.{16}[^0].{15}|.{17}[^0].{14}|.{18}[^0].{13}|.{19}[^0].{12}|.{20}[^0].{11}|.{21}[^0].{10}|.{22}[^0].{9}|.{23}[^0].{8}|.{24}[^0].{7}|.{25}[^0].{6}|.{26}[^0].{5}|.{27}[^0].{4}|.{28}[^0].{3}|.{29}[^0].{2}|.{30}[^0].|.{31}[^0])"|""),'
[awilk00@nvdejb-dc-2p ~]$ hostsettings='{"ServicePhone":"","SgxEpoch": "00000000000000000000000000000000","SgxEpochControl":"SgxEpochNoChange","DefaultBootOrder":["PcieSlotNic","EmbeddedFlexLOM","EmbeddedStorage","PcieSlotStorage","Usb","Cd","UefiShell","Floppy"]}'
[awilk00@nvdejb-dc-2p ~]$ desiredsettings='{"ServicePhone":"","SgxEpoch": "","SgxEpochControl":"SgxEpochNoChange","DefaultBootOrder":["Floppy","Cd","Usb","EmbeddedStorage","PcieSlotStorage","EmbeddedFlexLOM","PcieSlotNic","UefiShell"]}'
[awilk00@nvdejb-dc-2p ~]$ echo "${hostsettings}" | python -m json.tool | perl -00pe 's:[.*?]:($x=$&)=~s/s//gs;$x:ges'
{
    "DefaultBootOrder": ["PcieSlotNic","EmbeddedFlexLOM","EmbeddedStorage","PcieSlotStorage","Usb","Cd","UefiShell","Floppy"],
    "ServicePhone": "",
    "SgxEpoch": "00000000000000000000000000000000",
    "SgxEpochControl": "SgxEpochNoChange"
}
[awilk00@nvdejb-dc-2p ~]$ echo "${desiredsettings}" | python -m json.tool | perl -00pe 's:[.*?]:($x=$&)=~s/s//gs;$x:ges'
{
    "DefaultBootOrder": ["Floppy","Cd","Usb","EmbeddedStorage","PcieSlotStorage","EmbeddedFlexLOM","PcieSlotNic","UefiShell"],
    "ServicePhone": "",
    "SgxEpoch": "",
    "SgxEpochControl": "SgxEpochNoChange"
}
[awilk00@nvdejb-dc-2p ~]$ diff --report-identical-files --suppress-common-lines --side-by-side --ignore-matching-lines="${SgxEpochRegEx}" <(echo "${hostsettings}" | python -m json.tool | perl -00pe 's:[.*?]:($x=$&)=~s/s//gs;$x:ges') <(echo "${desiredsettings}" | python -m json.tool | perl -00pe 's:[.*?]:($x=$&)=~s/s//gs;$x:ges')
    "DefaultBootOrder": ["PcieSlotNic","EmbeddedFlexLOM","Emb |     "DefaultBootOrder": ["Floppy","Cd","Usb","EmbeddedStorage
    "SgxEpoch": "00000000000000000000000000000000",           |     "SgxEpoch": "",
[awilk00@nvdejb-dc-2p ~]$
[awilk00@nvdejb-dc-2p ~]$
[awilk00@nvdejb-dc-2p ~]$ hostsettings='{"ServicePhone":"","SgxEpoch": "5FSQUWEED6XPC8PJ2CWZGQIS4WWKLKUI","SgxEpochControl":"SgxEpochNoChange","DefaultBootOrder":["PcieSlotNic","EmbeddedFlexLOM","EmbeddedStorage","PcieSlotStorage","Usb","Cd","UefiShell","Floppy"]}'
[awilk00@nvdejb-dc-2p ~]$ echo "${hostsettings}" | python -m json.tool | perl -00pe 's:[.*?]:($x=$&)=~s/s//gs;$x:ges'
{
    "DefaultBootOrder": ["PcieSlotNic","EmbeddedFlexLOM","EmbeddedStorage","PcieSlotStorage","Usb","Cd","UefiShell","Floppy"],
    "ServicePhone": "",
    "SgxEpoch": "5FSQUWEED6XPC8PJ2CWZGQIS4WWKLKUI",
    "SgxEpochControl": "SgxEpochNoChange"
}
[awilk00@nvdejb-dc-2p ~]$ echo "${desiredsettings}" | python -m json.tool | perl -00pe 's:[.*?]:($x=$&)=~s/s//gs;$x:ges'
{
    "DefaultBootOrder": ["Floppy","Cd","Usb","EmbeddedStorage","PcieSlotStorage","EmbeddedFlexLOM","PcieSlotNic","UefiShell"],
    "ServicePhone": "",
    "SgxEpoch": "",
    "SgxEpochControl": "SgxEpochNoChange"
}
[awilk00@nvdejb-dc-2p ~]$ diff --report-identical-files --suppress-common-lines --side-by-side --ignore-matching-lines="${SgxEpochRegEx}" <(echo "${hostsettings}" | python -m json.tool | perl -00pe 's:[.*?]:($x=$&)=~s/s//gs;$x:ges') <(echo "${desiredsettings}" | python -m json.tool | perl -00pe 's:[.*?]:($x=$&)=~s/s//gs;$x:ges')
    "DefaultBootOrder": ["PcieSlotNic","EmbeddedFlexLOM","Emb |     "DefaultBootOrder": ["Floppy","Cd","Usb","EmbeddedStorage
[awilk00@nvdejb-dc-2p ~]$

注意:我几乎可以肯定,我在堆栈溢出上找到了一个线程,有人审查了diff的源代码并发现它可以按线进行比较,但找不到线程。

note2:我注意到,当diff在一条线之前找到区分线时,在 --suppress-common-lines Regex中会有匹配的线路时,diff不会删除匹配正则匹配的两条线,并立即将其显示为差异。在非regex匹配线之前,它发现了差异。希望我不会屠杀太糟糕。例如:

[~]$ SgxEpochRegEx='"SgxEpoch":s*("([^0].{31}|.[^0].{30}|.{2}[^0].{29}|.{3}[^0].{28}|.{4}[^0].{27}|.{5}[^0].{26}|.{6}[^0].{25}|.{7}[^0].{24}|.{8}[^0].{23}|.{9}[^0].{22}|.{10}[^0].{21}|.{11}[^0].{20}|.{12}[^0].{19}|.{13}[^0].{18}|.{14}[^0].{17}|.{15}[^0].{16}|.{16}[^0].{15}|.{17}[^0].{14}|.{18}[^0].{13}|.{19}[^0].{12}|.{20}[^0].{11}|.{21}[^0].{10}|.{22}[^0].{9}|.{23}[^0].{8}|.{24}[^0].{7}|.{25}[^0].{6}|.{26}[^0].{5}|.{27}[^0].{4}|.{28}[^0].{3}|.{29}[^0].{2}|.{30}[^0].|.{31}[^0])"|""),'
[~]$ desiredsettings='{"SgxEpoch": "","SgxEpochControl":"SgxEpochNoChange","DefaultBootOrder":["Floppy"]}'
[~]$ hostsettings='{"SgxEpoch": "5FSQUWEED6XPC8PJ2CWZGQIS4WWKLKUI","SgxEpochControl":"SgxEpochNoChange","DefaultBootOrder":["PcieSlotNic"]}'
[~]$ diff --report-identical-files --side-by-side --ignore-matching-lines="${SgxEpochRegEx}" <(echo "${hostsettings}" | python -m json.tool) <(echo "${desiredsettings}" | python -m json.tool)
{                                                               {
    "DefaultBootOrder": [                                           "DefaultBootOrder": [
        "PcieSlotNic"                                         |         "Floppy"
    ],                                                              ],
    "SgxEpoch": "5FSQUWEED6XPC8PJ2CWZGQIS4WWKLKUI",                 "SgxEpoch": "",
    "SgxEpochControl": "SgxEpochNoChange"                           "SgxEpochControl": "SgxEpochNoChange"
}                                                               }
[~]$ diff --report-identical-files --side-by-side --ignore-matching-lines="${SgxEpochRegEx}" <(echo "${hostsettings}" | python -m json.tool | grep -v '[]],') <(echo "${desiredsettings}" | python -m json.tool | grep -v '[]],')
{                                                               {
    "DefaultBootOrder": [                                           "DefaultBootOrder": [
        "PcieSlotNic"                                         |         "Floppy"
    "SgxEpoch": "5FSQUWEED6XPC8PJ2CWZGQIS4WWKLKUI",           |     "SgxEpoch": "",
    "SgxEpochControl": "SgxEpochNoChange"                           "SgxEpochControl": "SgxEpochNoChange"
}                                                               }
[~]$

由于数据的敏感性,我想确保我清楚地了解了这条正则是如何工作的。

,我也非常感谢您在巨大的正则线条上提供的任何语法验证,因为我不太了解它的工作原理。

此处的要求是要有人解释/验证正则条件。我认为最好是因为XY问题解释我的最终目标,但实际上我负担不起当前重新编写所有内容的时间投资。我对此持开放态度,但我有一个约会。

aaron

您的正则表达式似乎很好。也许问题是diff--ignore-matching-lines选项(Shorthand -I(,其作用与人们期望的不同。

diff -I regex如何工作?

ab为两个文件。

如果我没有阅读文档,我希望以下两个命令等效:

diff -I regex a b
diff <(grep -v regex a) <(grep -v regex b)

这两种方式是错误的:

  • diff总是考虑 Pairs ab的行。如果两行(a的线和b的行(都匹配这对。

  • 即使两对匹配的两行,也可能会忽略它们。不仅两对中的两行都必须匹配,而且的所有线条都必须匹配!

第二点的示例(-y--side-by-side的速记(:

diff --suppress-common-lines -yI '1|2' <(printf '1n') <(printf '2n')
diff --suppress-common-lines -yI '1|2' <(printf '1n1n') <(printf '2nXn')
1                                 | 2
1                                 | X

第一个命令按预期工作,但第二个命令没有。而不是线对(12(diff试图匹配块中的所有行((( 11(,( 2X((。那个大块的一行与整个大块的印刷不匹配。

替代diff -I

我不完全确定您的典型输入和预期输出是什么。我猜是:

  • 您的文件original可能包含该行
    "SgxEpoch": "00000000000000000000000000000000"

  • 您生成的文件generated将0线修复到
    之类的东西 "SgxEpoch": "5FSQUWEED6XPC8PJ2CWZGQIS4WWKLKUI"

  • (您需要帮助的地方(
    您想比较两个文件originalgenerated,以确保第二步中的脚本做正确的事情。为了使比较更容易,您只想看到original的相应行是
    "SgxEpoch": "00000000000000000000000000000000"

    "SgxEpoch": ""

有一个简单的解决方案。只需抓取diff的输出:

diff --suppress-common-lines -y original generated |
grep -E '^s*"SgxEpoch"s*:s*"0*"'

最新更新