匹配文件中的行,其中有 2 个按顺序排列的字符串列表

匹配文件中的行,其中有 2 个按顺序排列的字符串列表

我试图匹配文件中的访问列表行,其中某些环境(列表 A)是目标,其他环境(列表 B)是源。反之亦然。

这是在 Ubuntu 服务器上。

问题是这些列表都大约有 15 行,这导致了相当多的组合和一个非常长的 grep 命令。正在搜索的文件总共大约有 3000 行。

我知道我可以通过 匹配文件中的行与文件中的行grep -f,但我无法找到满足我的特定搜索要求的解决方案,我从两个列表中搜索,并且顺序很重要。

我想要做的示例(括号是故意的,因为我正在一个文件中搜索,该文件的每行 IP 地址都附加了相关环境):

清单A内容:

(One)
Two
Three

B表内容:

(Four)
(Five)
(Six)

正在搜索的文件:

access-list acl-name line 1 extended permit tcp host 1.2.3.4 (One) host 5.6.7.8 Two eq ssh
access-list acl-name line 1 extended permit tcp host 1.2.3.4 (One) host 5.6.7.8 (Four) eq ssh
access-list acl-name line 1 extended permit tcp host 1.2.3.4 (Four) host 5.6.7.8 Three eq ssh
access-list acl-name line 1 extended permit tcp host 1.2.3.4 (Six) host 5.6.7.8 (One) eq ssh
access-list acl-name line 1 extended permit tcp host 1.2.3.4 (Five) host 5.6.7.8 (Five) eq ssh

所需的输出(列表 A 作为目标):

access-list acl-name line 1 extended permit tcp host 1.2.3.4 (Six) host 5.6.7.8 (One) eq ssh
access-list acl-name line 1 extended permit tcp host 1.2.3.4 (Four) host 5.6.7.8 Three eq ssh

所需的输出(列表 B 作为目标):

access-list acl-name line 1 extended permit tcp host 1.2.3.4 (One) host 5.6.7.8 (Four) eq ssh

我对 Ubuntu 上可用的任何命令甚至 python 脚本持开放态度。

现在,我的 grep 搜索看起来像这样(用于匹配列表 B 是目标、列表 A 是源的行)

grep -iE '\(One\).*\(Four\)|Two.*\(Four\)|Three.*\(Four\)|\(One\).*\(Five\) and so on... '

感谢您的帮助,因此我希望可以将当前脚本的字符数从 15000 个字符减少:)

答案1

假设您有可用的 GNU Awk(对于FPAT内部变量),以下程序应该可以工作:

awk 'BEGIN{FPAT="host ([[:digit:]]+.){3}[[:digit:]]+ [^ ]+"}
     t=="src"{src[$0];next}
     t=="dst"{dest[$0];next}
     {split($1,a,/ /);lsrc=a[3]; split($2,a,/ /);ldst=a[3]}
     (lsrc in src && ldst in dest)' t="src" listA t="dst" listB t="" access

该程序将被调用并处理三个文件,其中对于每个处理运行,变量awkt设置为不同的值以允许识别哪个文件被处理。

  • 如果t设置为src,则程序假定这是“源”列表并将行内容读入关联数组src(但仅填充数组索引,而不实际为该条目分配任何值)。然后处理立即跳到文件的下一行。请注意,不能有前导或尾随空格,否则它们将包含在模式匹配中。另外,稍后的匹配将假定这些行仅包含一个连续的字符串,没有内部空格。
  • 如果t设置为dst,则程序假定这是“目标”列表,并将类似地将所有行内容注册到数组中dest

如果t有任何其他值,则程序假定它位于“主”访问列表中并执行实际匹配。

  • 在这里,FPAT在该部分中设置的内部变量BEGIN开始发挥作用。它将把与模式匹配的所有部分视为“字段” host,后跟 IPv4 地址(仅执行基本的形式检查),后跟单个连续字符串,每个字符串由单个空格分隔”。
  • 第一个这样的字段包含“源”部分。它将在空格处分割成一个数组a,第三个数组条目(“环境”部分)存储在局部变量中lsrc
  • 第二个这样的字段将被类似地处理,“环境”部分存储在局部变量中ldst
  • 规则块之外是布尔条件,它将确定是否打印该行。如果lsrc包含在数组的索引中,则打印该行src theldst包含在 array 的索引中dest

listA用作第一个文件和第二个文件的结果listB将是:

> awk ' ... ' t="src" listA t="dst" listB t="" access
access-list acl-name line 1 extended permit tcp host 1.2.3.4 (One) host 5.6.7.8 (Four) eq ssh

在相反的情况下,用作listB第一个文件和listA第二个文件:

> awk ' ... ' t="src" listB t="dst" listA t="" access
access-list acl-name line 1 extended permit tcp host 1.2.3.4 (Four) host 5.6.7.8 Three eq ssh
access-list acl-name line 1 extended permit tcp host 1.2.3.4 (Six) host 5.6.7.8 (One) eq ssh

相关内容