我正在 CentOS 7 中工作,尝试使用 find / sed oneliners 来修复大量文件。具体来说是连续两个:
[monitor://...]
首先,在每个(工作)之后立即添加“ignoreOlderThan = 14d”- 其次,找到一个
[monitor://...]
具有两个“ignoreOlderThan”的组并删除最后一个出现的情况。
我有数百个与此类似的文件(这是我正在使用的当前测试文件):
[default]
host = 10.2.2.15
[monitor://apath]
ignoreOlderThan = 14d
index=test
sourcetype=whatever
ignoreOlderThan = 30d
[monitor://truck]
ignoreOlderThan = 14d
[monitor://apath]
ignoreOlderThan = 14d
index=test
sourcetype=whatever
ignoreOlderThan = 30d
我使用的第一个完整命令是:
find -name inputs.conf -exec sed -ie 's/\(\[monitor:.*\]\)/\1\nignoreOlderThan = 14d/g' {} +
这个有效。它ignoreOlderThan = 14d
紧接着添加在[monitor://...]
.
第二个更复杂,不起作用:
find -name inputs.conf -exec sed -ie 's/\(\[monitor[^\]]+\][^\[]?\)\(ignoreOlderThan\s?=\s?[0-9]+\w\)\([^\[]+?ignoreOlderThan\s?=\s?[0-9]+\w\)\([^\[]+\)?/\1\3\4/g' {} +
我使用 regex101 测试了几种可能的场景:
https://regex101.com/r/okCSfl/6
https://regex101.com/r/okCSfl/7
https://regex101.com/r/okCSfl/8
https://regex101.com/r/okCSfl/9
正则表达式有效,所以我认为问题出在 sed 命令中的某个地方,而我的能力要弱得多。我已经根据捕获组的需要转义了括号,并且命令运行......但它没有执行任何操作。我认为这可能是因为有时第四个捕获组不存在,但我还测试了一个文件,其中每个组都包含所有 4 个捕获组。
我还读到一些 sed 将所有内容解释为一行,这就是为什么我的一些测试用例在换行符之间根本没有空格。
编辑:@choroba 指出 sed 一次执行一行并建议 perl 并给出了一个例子。我玩了一下并让它与以下内容一起工作:
find -name inputs.conf -exec perl -0777 -pi -e 's/(\[monitor:[^[]+?)^(ignoreOlderThan\s?=\s?[0-9]+\w)([^[]+?^ignoreOlderThan\s?=\s?[0-9]+\w[^[]+)/$1$3/gms' {} +
此处演示:
答案1
sed 逐行处理输入。它的正则表达式不能轻易匹配多行。
另一方面,当-0777
指定选项时,Perl 可以读取整个文件:
perl -0777 -pe 's/^(\[monitor:[^[]+^ignoreOlderThan .*)^ignoreOlderThan = \w+/$1/gms' input > output
-0777
吞掉整个文件-p
处理后打印输入/g
重复替换/s
匹配.
换行符(通常不会)/m
^
在每个换行符的开头进行匹配,而不仅仅是整个字符串(类似地$
,但我们在这里不需要它)