我有两个文件:master.tbl
和sites.lst
该文件master.tbl
是站点列表,包含其端口配置、端口名称、IP 地址等。有些行包含站点描述、注释等,但它们是不相关的。包含站点配置的行如此排列,并由空格分隔:
{server} {SITE NAME} {port name} {configuration flags}
端口名称由小写站点名称、破折号、“P”和端口号组成。
例子:
server01 HAWAII23-USR hawaii23-P1 blah-configuration-blah-arguments
server01 HAWAII23-ADM hawaii23-P2 blah-configuration-blah-arguments
server01 HAWAII23-ADM hawaii23-P3 blah-configuration-blah-arguments
server01 HAWAII23-USR hawaii23-P4 blah-configuration-blah-arguments
sites.lst
是我需要搜索文件的网站列表master.tbl
。
我需要注释掉(#
在行首插入 a ),并提取stoplist.lst
满足以下所有条件的每一行的服务器名称和端口名称(到名为 的文件中):
- 包含中列出的任何站点名称
sites.lst
- 包含“-ADM”
- 端口号大于“2”(示例
hawaii23-P3
:)
在上面的示例中,该master.tbl
文件将如下所示:
server01 HAWAII23-USR hawaii23-P1 blah-configuration-blah-arguments
server01 HAWAII23-ADM hawaii23-P2 blah-configuration-blah-arguments
#server01 HAWAII23-ADM hawaii23-P3 blah-configuration-blah-arguments
server01 HAWAII23-USR hawaii23-P4 blah-configuration-blah-arguments
...并且stoplist.lst
将包含(假设HAWAII23
位于 中sites.lst
):
server01 hawaii23-P3
master.lst
几乎有 300,000 行,所以手动执行此操作会......很糟糕。
答案1
这是一个awk
解决方案:
awk 'NR==FNR{z[$0"-ADM"]++;next}
{p=$3;sub(/.*-P/, "", p); if ($2 in z && p > 2)
{print $1,$3 > "stoplist.lst"; $0="#"$0}}1' sites.lst master.tbl
sites.lst
首先读取并将$0"-ADM"
(即站点名称 + 字符串-ADM
)设置为数组的索引z
。然后,它会将第三个字段中master.tbl
的值提取为and,如果满足条件(第二个字段在且大于 2),它将打印第一个和第三个字段并将该行注释掉。 请注意,它不会就地编辑文件,但如果一切正常,您始终可以重定向到另一个文件并覆盖原始文件(尽管最近您可以选择)。-P
p
z
p
stoplist.lst
gnu awk
-i inplace