CPUNAME AGENT_1
DESCRIPTION "MANAGER CPU"
OS UNIX
NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
DOMAIN MASTERDM
FOR MAESTRO
TYPE MANAGER
IGNORE
AUTOLINK ON
BEHINDFIREWALL OFF
FULLSTATUS ON
END
CPUNAME AGENT_2
DESCRIPTION "MANAGER CPU"
OS UNIX
NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
TIMEZONE abc
DOMAIN MASTERDM
FOR MAESTRO
TYPE MANAGER
IGNORE
AUTOLINK ON
BEHINDFIREWALL OFF
FULLSTATUS ON
END
CPUNAME AGENT_3
DESCRIPTION "MANAGER CPU"
OS UNIX
NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
TYPE MANAGER
IGNORE
AUTOLINK ON
BEHINDFIREWALL OFF
FULLSTATUS ON
END
DOMAIN MASTERDM
*MANAGER AGENT_1
ISMASTER
END
首先在上面的文件中,我在模式匹配“TYPE”之后附加了一行“IGNORE”。
sed -i '/^ TYPE.*/a IGNORE' filename
我需要删除特定CPU的IGNORE标志,例如AGENT_1 AGENT_3,但是IGNORE的位置并不固定,如上所示。不同街区的第 8、9 和 6 号即将到来。截至目前,我知道我正在编辑文件 IGNORE 标志的 CPU 位于第 8 个位置,因此我使用了一个
for
循环并删除了 IGNORE。for s in `cat $INPUT_FILE | awk '{print $1}'`; do echo $s sed -i "/$s/!b;n;n;n;n;n;n;n;d" Filename done
据我所知,所有块的 NODE 位置始终是固定的,我使用以下命令来替换该行。
for n in `cat $INPUT_FILE`; do CPU=$(echo $n | cut -f1) NODE=$(echo $n | cut -f2) echo "$CPU" echo "$NODE" sed -i "/$CPU/!b;n;n;n;c $NODE" filename done
以上所有工作正常,除了删除特定 CPU 的忽略(如果它不是固定线路)。请提供您宝贵的建议来改进解决方案。
答案1
任务:删除IGNORE
指定 CPU 名称的行
如果你想删除该IGNORE
行AGENT_1
,AGENT_3
你可以使用
awk '$1 == "CPUNAME" && ($2 == "AGENT_1" || $2 == "AGENT_3") { x=1 }
/^END$/ { x=0 }
x && /^ *IGNORE$/ { next }
1' inputfile
您可以根据需要在条件中添加或删除 CPU 名称。
这会将修改后的数据打印到标准输出。一般来说,我不建议就地编辑,因为如果出现任何问题,您可能会丢失数据。如果您确实想用不支持就地编辑的工具替换输入文件,您始终可以使用类似
awk 'some script' inputfile > tempfile && mv tempfile inputfile
解释
$1 == "CPUNAME" && ($2 == "AGENT_1" || $2 == "AGENT_3")
如果第一个字段是CPUNAME
并且第二个字段是指定名称之一,则条件匹配。{ x=1 }
设置标志x
来标记我们要IGNORE
在此块中删除的内容/^END$/ { x=0 }
如果整行与块末尾的END
清除标志匹配。x
x && /^ *IGNORE$/
仅当设置了IGNORE
标志时才匹配带有前导空格的行的条件。x
{ next }
跳过该行的进一步处理,即不打印它。1
是一个true
(=每行)条件,没有默认为 的操作print
。 (您可以将其写得更详细,如{ print }
。)
使用问题中的示例输入
CPUNAME AGENT_1
DESCRIPTION "MANAGER CPU"
OS UNIX
NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
DOMAIN MASTERDM
FOR MAESTRO
TYPE MANAGER
IGNORE
AUTOLINK ON
BEHINDFIREWALL OFF
FULLSTATUS ON
END
CPUNAME AGENT_2
DESCRIPTION "MANAGER CPU"
OS UNIX
NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
TIMEZONE abc
DOMAIN MASTERDM
FOR MAESTRO
TYPE MANAGER
IGNORE
AUTOLINK ON
BEHINDFIREWALL OFF
FULLSTATUS ON
END
CPUNAME AGENT_3
DESCRIPTION "MANAGER CPU"
OS UNIX
NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
TYPE MANAGER
IGNORE
AUTOLINK ON
BEHINDFIREWALL OFF
FULLSTATUS ON
END
DOMAIN MASTERDM
*MANAGER AGENT_1
ISMASTER
END
输出是
CPUNAME AGENT_1
DESCRIPTION "MANAGER CPU"
OS UNIX
NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
DOMAIN MASTERDM
FOR MAESTRO
TYPE MANAGER
AUTOLINK ON
BEHINDFIREWALL OFF
FULLSTATUS ON
END
CPUNAME AGENT_2
DESCRIPTION "MANAGER CPU"
OS UNIX
NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
TIMEZONE abc
DOMAIN MASTERDM
FOR MAESTRO
TYPE MANAGER
IGNORE
AUTOLINK ON
BEHINDFIREWALL OFF
FULLSTATUS ON
END
CPUNAME AGENT_3
DESCRIPTION "MANAGER CPU"
OS UNIX
NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
TYPE MANAGER
AUTOLINK ON
BEHINDFIREWALL OFF
FULLSTATUS ON
END
DOMAIN MASTERDM
*MANAGER AGENT_1
ISMASTER
END
反向任务:插入IGNORE
行
如果真实的输入文件没有IGNORE
行,您还可以使用一个脚本,仅将这些行插入到该行后与指定 CPU 名称匹配(或不匹配)的块中TYPE
。
示例:插入与和IGNORE
都不匹配的块AGENT_1
AGENT_3
awk '$1 == "CPUNAME" && ($2 != "AGENT_1" && $2 != "AGENT_3") { x=1 }
/^END$/ { x=0 }
1
x && $1 == "TYPE" { print " IGNORE" }' inputfile
解释:(仅与第一个脚本不同的地方)
$1 == "CPUNAME" && ($2 != "AGENT_1" && $2 != "AGENT_3")
第一个字段CPUNAME
和第二个字段都不是这两个名称。x && $1 == "TYPE"
标志x
已设置,第一个字段是TYPE
{ print " IGNORE" }
打印IGNORE
行(TYPE
行后)
AGENT_1
使用 CPU ..AGENT_4
且无行的示例输入IGNORE
:
CPUNAME AGENT_1
DESCRIPTION "MANAGER CPU"
OS UNIX
NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
DOMAIN MASTERDM
FOR MAESTRO
TYPE MANAGER
AUTOLINK ON
BEHINDFIREWALL OFF
FULLSTATUS ON
END
CPUNAME AGENT_2
DESCRIPTION "MANAGER CPU"
OS UNIX
NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
TIMEZONE abc
DOMAIN MASTERDM
FOR MAESTRO
TYPE MANAGER
AUTOLINK ON
BEHINDFIREWALL OFF
FULLSTATUS ON
END
CPUNAME AGENT_3
DESCRIPTION "MANAGER CPU"
OS UNIX
NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
TYPE MANAGER
AUTOLINK ON
BEHINDFIREWALL OFF
FULLSTATUS ON
END
CPUNAME AGENT_4
DESCRIPTION "MANAGER CPU"
OS UNIX
NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
TYPE MANAGER
AUTOLINK ON
BEHINDFIREWALL OFF
FULLSTATUS ON
END
DOMAIN MASTERDM
*MANAGER AGENT_1
ISMASTER
END
结果输出:
CPUNAME AGENT_1
DESCRIPTION "MANAGER CPU"
OS UNIX
NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
DOMAIN MASTERDM
FOR MAESTRO
TYPE MANAGER
AUTOLINK ON
BEHINDFIREWALL OFF
FULLSTATUS ON
END
CPUNAME AGENT_2
DESCRIPTION "MANAGER CPU"
OS UNIX
NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
TIMEZONE abc
DOMAIN MASTERDM
FOR MAESTRO
TYPE MANAGER
IGNORE
AUTOLINK ON
BEHINDFIREWALL OFF
FULLSTATUS ON
END
CPUNAME AGENT_3
DESCRIPTION "MANAGER CPU"
OS UNIX
NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
TYPE MANAGER
AUTOLINK ON
BEHINDFIREWALL OFF
FULLSTATUS ON
END
CPUNAME AGENT_4
DESCRIPTION "MANAGER CPU"
OS UNIX
NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
TYPE MANAGER
IGNORE
AUTOLINK ON
BEHINDFIREWALL OFF
FULLSTATUS ON
END
DOMAIN MASTERDM
*MANAGER AGENT_1
ISMASTER
END
答案2
使用乐(以前称为 Perl_6)
~$ raku -e 'my @a = slurp.split("\n\n"); .subst(" IGNORE\n").put if .match(/AGENT_1 | AGENT_3/) for @a;' file
简而言之,上面的代码使用 Raku 编程语言。使用 读取整个文件slurp
,并按\n\n
连续的换行符拆分为记录,这些记录存储在数组 中@a
。然后,如果记录match
是所需的任何一个AGENT
,则该记录将被删除put
,其中“ IGNORE\n
”行不被任何内容替换(即被删除)。