我的测试文件test.txt如下:
destination mailerr { file("/var/log/mail.err" fsync(yes)); };
log { source(src); filter(f_mailerr); destination(mailerr); };
#
# and also all in one file:
#
destination mail { file("/var/log/mail"); };
log { source(src); filter(f_mail); destination(mail); };
destination mailwarn { file("/var/log/mail.warn"); };
log
{
#source(src);
filter(f_mailwarn); destination(mailwarn); };
我想使用shell脚本删除以下行
log
{
#source(src);
filter(f_mailwarn); destination(mailwarn); };
这些行可能会有不同的结构,如
log{ source(src); filter(f_mailwarn); destination(mailwarn); };
(or)
log
{
source(src);
filter(f_mailwarn);
destination(mailwarn);
};
(or)
log
{ source(src); filter(f_mailwarn); destination(mailwarn); };
(or)
# log { source(src); filter(f_mailwarn); destination(mailwarn); };
};
这些是可能性。我正在使用sed命令:
sed '/log/{:a;/destination(mailwarn);.*}/d;N;ba}' test.txt
但它会删除所有行,因为第一行它自己“log”来了。这么多“log”都出现在这个文件中,所以如何使用shell脚本删除特定的行。
答案 0 :(得分:1)
您可以试试sed
:
sed '/^[# ]*log/{:loop; /destination(.*}/d; /}/{n}; N; b loop;}' file
<强>解释强>
/^[# ]*log/
- 在{}
匹配时开始处理阻止regex
。/destination(.*}/d
- 删除regex
匹配时的模式空间。开始一个新的周期。/}/{n}
- 当找到}
时,打印模式空间并读取下一行输入。 (用于打印非log...destination()
行。N
- 这会将下一行输入附加到模式空间。b loop
- 这会将流量控制转移到loop
。答案 1 :(得分:1)
如果文件不是太大,请使用-z
选项一次性处理整个文件(@ SLePort注意这是GNU特定选项)
sed -z 's/log[ \t\n]*{[^}]*destination(mailwarn);[ \t\n]*};//g' test.txt
log
比赛开始[ \t\n]*{
零个或多个非空格/制表符/换行符后跟{
log/mail.warn"); };
如果使用[^{]*{
[^}]*
零个或多个非}
个字符destination(mailwarn);
要匹配的字符串[ \t\n]*};
零个或多个非空格/制表符/换行符后跟};
与perl
perl -0777 -pe 's/log\s*\{[^}]*destination\(mailwarn\);\s*};//g' test.txt
答案 2 :(得分:0)
使用sed:
sed '/^#*[[:blank:]]*log/{:a;/};/!{N;ba;s/\n//;};/destination(mailwarn)/d;}' file
将log
到};
的行添加到模式空间,在其中搜索destination(mailwarn)
,如果找到,则删除行。
答案 3 :(得分:0)
这是我完成工作的有点方式。它似乎适用于您发布的所有案例,但绝不是解决此问题的通用解决方案。
tr '\n' '\0' < test.txt | sed 's/log[^{}]*{[^}]*destination(mailwarn);[^}]*};//g' | tr '\0' '\n'
如果test.txt
包含空字符,则可能无法正常工作。此命令主要查找log
后跟{
,然后到达}
destination(mailwarn);
,最后跟};
,并删除此项匹配如果找到。
我希望其他人为这个问题发布更强大的解决方案,但这是我能够提出的唯一快速解决方案。