我试图匹配文件中的访问列表行,其中某些环境(列表 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
该程序将被调用并处理三个文件,其中对于每个处理运行,变量awk
被t
设置为不同的值以允许识别哪个文件被处理。
- 如果
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