[英]sed or perl regex replace section in file
我有一个文件,正在尝试正则表达式删除具有以下内容的行:
flannel:
interface: $private_ipv4
etcd_endpoints: {{ .ETCDEndpoints }}
我尝试使用此perl命令,最终将所有内容从#cloud-config删除,直到-名称:docker.service
perl -i -00ne 'print unless /(flannel:).*([^ ]+).*([^ ]+).*}}/' file.txt
file.txt:
#cloud-config
coreos:
update:
reboot-strategy: "off"
flannel:
interface: $private_ipv4
etcd_endpoints: {{ .ETCDEndpoints }}
etcd2:
name: controller
advertise-client-urls: http://$private_ipv4:2379
initial-advertise-peer-urls: http://$private_ipv4:2380
listen-client-urls: http://0.0.0.0:2379
listen-peer-urls: http://0.0.0.0:2380
initial-cluster: controller=http://$private_ipv4:2380
units:
- name: etcd2.service
command: start
runtime: true
- name: docker.service
drop-ins:
- name: 40-flannel.conf
content: |
[Unit]
Requires=flanneld.service
After=flanneld.service
[Service]
EnvironmentFile=/etc/kubernetes/cni/docker_opts_cni.env
...
根据您显示的确切文字
perl -0777 -ne 's/flannel:[^}]+}//; print' file.txt
这是通过观察到要删除的文本中没有}
起作用的。 因此,它使用否定的字符类 [^}]
来匹配}
以外的任何字符。 因此,使用+
可以匹配第一个}
。 在perlretut和perlrecharclass中看到此内容 。 请调整其他文字。
或使用
perl -0777 -ne 's/flannel:.+?(?=etcd2:)+//s; print' file.txt
使用正向前瞻 (?=...)
这是一个零宽度断言 ,这意味着它匹配到该模式和不消耗它。 它只是“看起来”(断言)它在那里。 在perlretut中看到它。 在这种情况下,我们还需要使用/s
修饰符 ,即.
也匹配换行符。
-0[oct/hex]
开关设置输入记录分隔符 $/
。 -00
将其设置为空行,从而按段落读取,这不是您所需要的。 -0
用null
字符分割输入,这是不太可能出现在文件中的,因此通常它可以“工作”以一次读取整个文件。 但要发出声音文件的正确方法是指定任何大于-0400
和-0777
习惯。 请参见perlrun中的命令行开关
在这里,您可以使用-p
代替-n
,然后删除print
,因为-p
打印$_
。
在命令行规范-00ne
,您要求的是“段落”模式(两个零)。 如果我正确理解您的问题,我认为您想对文件进行处理。 那将使用一个零。
我用perl -0777 -pe 's/^\\s+flannel:.+?(?=^\\s+etcd2)//ms' file.txt
来获取我认为您想要的:
注意标记ms
。 m
在“行”的开头使^
匹配,而不是在“字符串”的开头进行匹配的默认行为。 并且s
标志允许点(。)也可以匹配换行符,这在我给出的解决方案中是必需的。
#cloud-config
coreos:
update:
reboot-strategy: "off"
etcd2:
name: controller
advertise-client-urls: http://$private_ipv4:2379
initial-advertise-peer-urls: http://$private_ipv4:2380
listen-client-urls: http://0.0.0.0:2379
listen-peer-urls: http://0.0.0.0:2380
initial-cluster: controller=http://$private_ipv4:2380
units:
- name: etcd2.service
command: start
runtime: true
- name: docker.service
drop-ins:
- name: 40-flannel.conf
content: |
[Unit]
Requires=flanneld.service
After=flanneld.service
[Service]
EnvironmentFile=/etc/kubernetes/cni/docker_opts_cni.env
它是YAML,因此请使用YAML解析器。
#!/usr/bin/env perl
use strict;
use warnings;
use YAML::XS;
use Data::Dumper;
# <> is the magic file handle, it reads files on command line or STDIN.
# much like grep/sed/awk do.
my $conf = Load ( do { local $/; <> } );
#print for debugging.
print Dumper $conf;
#delete the key you don't want.
delete $conf->{coreos}{flannel};
#print output to STDOUT.
#You can hack this into in place editing if you
#want.
print Dump $conf;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.