繁体   English   中英

在 Perl 中的某个特定匹配项下方编辑/匹配字符串 n 行?

[英]Edit/Match a string n lines below some specific match in Perl?

您好最近我发布了一个问题。 在 bash 中的行匹配下编辑第 n 行?
(问题:我必须在[MARATHON]下面编辑PROTOCOL行 3 行)

这是文件:

# /etc/ndxconfig.ini will override this file
# if APP_ID is added in service propery, service discovery will be using marathon;
# HOST/PORT specified will override values retrieved from marathon

[MARATHON]
HOSTS = {{ ','.join(groups['marathon'])}}
PORT = 8080
PROTOCOL = http
SECRET = SGpQIcjK2P7RYnrdimhhhGg7i8MdmUqwvA2JlzbyujFS4mR8M88svI7RfNWt5rnKy4WHnAihEZmmIUb940bnlYmnu47HdUHE


[MYSQL]
; APP_ID = /neon/infra/mysql
HOST = {{keepalived_mysql_virtual_ip}}
PORT = 3306
SECRET = tIUFN1rjjDBdEXUsOJjPEtdieg8KhwTzierD48JsgDeYc84DD6Uy5a6kzHfKolq1MNS1DKwlSqxENk33UulJd9DPHPzYCxFm

问题是如果我在某些情况下重新运行脚本,
sed '/\[MARATHON\]/{N;N;N;s/http/https/;}' <file>httpsssss越来越多shttp
所以我会在s的正则表达式中添加一个积极的前瞻性。 我可以用perl -pe做到这一点,但不知道我是如何在比赛下方的第 n 行做到这一点的 请帮忙。 我该怎么做?

如果您使用的是 GNU sed,则解决方案可以使用字边界:

sed '/\[MARATHON\]/{N;N;N;s/\<http\>/https/;}' file 
#                          ^^     ^^

您还可以利用上下文详细信息。 由于httpPROTOCOL之后,您可以简单地使用它来重置值:

sed '/\[MARATHON\]/{N;N;N;s/\(.*= *\).*/\1https/;}' file 

\(.*= *\).*将匹配并捕获带有=和可选空格的键,并使用\1恢复其值,而https将始终重写该值。

试试这个单行,它完全符合您的要求:在 Perl 中的某个特定匹配项下方编辑一个字符串 n 行 但也要考虑下面的注释

cat file | perl -lpe '
$seen = 1 if m{\[MARATHON\]}xms;
$num_lines++ if $seen;
s{ \A ( PROTOCOL \s+ = \s+ ) http }{${1}https}xms if $num_lines == 4;
'

笔记:

上面的代码回答了这个问题,但它是糟糕的代码。 为什么? 依靠预期的模式和预期的行数来解析已知的、广泛使用的格式通常是一个坏主意。 在这里,格式似乎是.ini ,因此请考虑搜索用于解析/读取/写入config ini文件的模块/库。 例如:

如果您不想使用上述模块,请至少考虑将来可能对输入进行更改并在代码中使用更少的假设。 在这种情况下,header 部分中第n行的假设似乎是难以改变的。 编写此文件的上游代码中的ini解析器可能不关心行的顺序。 节标题更健壮。 也许阅读整个文件( slurp )并使用从[MARATHON]PROTOCOL = http https 不要指定确切的行数,只需确保您更改的行在同一部分中。 但这仍然是在重新发明轮子——如果可以的话,请避免这样做。

也可以看看:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM