[英]Sed insert line multiple times on pattern
I have 我有
/var/log/syslog
{
rotate 7
daily
missingok
notifempty
delaycompress
compress
postrotate
invoke-rc.d rsyslog rotate > /dev/null
endscript
}
/var/log/mail.info
/var/log/mail.warn
/var/log/mail.err
/var/log/mail.log
/var/log/daemon.log
/var/log/kern.log
/var/log/auth.log
/var/log/user.log
/var/log/lpr.log
/var/log/cron.log
/var/log/debug
/var/log/messages
{
rotate 4
weekly
missingok
notifempty
compress
delaycompress
sharedscripts
postrotate
invoke-rc.d rsyslog rotate > /dev/null
endscript
}
What I want to do is insert olddir /var/log/oldlog
a line before the top rotate 7
and lower rotate 4
lines. 我想要做的是在顶部
rotate 7
和下部rotate 4
行之前插入olddir /var/log/oldlog
一行。 Is it possible to make sed
do possible multiple insertions? 有可能使
sed
可以进行多次插入吗? Also it also needs to ignore the rotate >
pattern in the postrotate. 此外,它还需要忽略postrotate中的
rotate >
pattern。
I thought I would ask before I try and do something longwinded and horrid. 在我尝试做一些长篇大论和可怕的事情之前,我想我会问。 Also the above is the main question but a secondary one would be to iterate all files in the directory with the above.
以上是主要问题,但次要问题是使用上述内容迭代目录中的所有文件。
Any pointers would be really appreciated 任何指针都会非常感激
Input: 输入:
$ cat input_file
/var/log/syslog
{
rotate 7
daily
missingok
notifempty
delaycompress
compress
postrotate
invoke-rc.d rsyslog rotate > /dev/null
endscript
}
/var/log/mail.info
/var/log/mail.warn
/var/log/mail.err
/var/log/mail.log
/var/log/daemon.log
/var/log/kern.log
/var/log/auth.log
/var/log/user.log
/var/log/lpr.log
/var/log/cron.log
/var/log/debug
/var/log/messages
{
rotate 4
weekly
missingok
notifempty
compress
delaycompress
sharedscripts
postrotate
invoke-rc.d rsyslog rotate > /dev/null
endscript
}
Command: 命令:
sed -i.bak '/rotate [0-9]\+/{s@^\( \+\)@\1olddir /var/log/oldlog\n\1@}' input_file
Output: 输出:
$ cat input_file
/var/log/syslog
{
olddir /var/log/oldlog
rotate 7
daily
missingok
notifempty
delaycompress
compress
postrotate
invoke-rc.d rsyslog rotate > /dev/null
endscript
}
/var/log/mail.info
/var/log/mail.warn
/var/log/mail.err
/var/log/mail.log
/var/log/daemon.log
/var/log/kern.log
/var/log/auth.log
/var/log/user.log
/var/log/lpr.log
/var/log/cron.log
/var/log/debug
/var/log/messages
{
olddir /var/log/oldlog
rotate 4
weekly
missingok
notifempty
compress
delaycompress
sharedscripts
postrotate
invoke-rc.d rsyslog rotate > /dev/null
endscript
}
Explanations: 说明:
-i.bak
will activate the option to take a backup of each file before modifying them and add the suffix .bak
at the end of each filename. -i.bak
将在修改每个文件之前激活备份以备份每个文件,并在每个文件名末尾添加后缀.bak
。 /rotate [0-9]\\+/
will only take the lines that contain rotate
followed by a space and an integer /rotate [0-9]\\+/
将仅包含包含rotate
的行,后跟空格和整数 sed
encounters one of those lines, it will execute s@^\\( \\+\\)@\\1olddir /var/log/oldlog\\n\\1@
which is a find and replace command that will replace the beginning of the line as well as all the spaces by the pattern. sed
遇到其中一行时,它将执行s@^\\( \\+\\)@\\1olddir /var/log/oldlog\\n\\1@
这是一个find和replace命令,它将该行的开头替换为以及模式的所有空间。 I have taken into account the spaces to keep the indentation by using back reference \\1
. \\1
来保持缩进的空格。 2nd question: 第二个问题:
find /path/to/my/files -type f -exec sed -i.bak '/rotate [0-9]\+/{s@^\( \+\)@\1olddir /var/log/oldlog\n\1@}' {} \;
You might add -name 'YOUR FILE PATTERN'
if you want to reduce the find scope. 如果要减少查找范围,可以添加
-name 'YOUR FILE PATTERN'
。 Also consider using -maxdepth N
to limit the depth in term of subdirs of the search 还可以考虑使用
-maxdepth N
来限制搜索子目录的深度
Update: 更新:
As the text contains a mix of \\t
and spaces, we can use the following POSIX class [:blank:]
that will match those 2 characters. 由于文本包含
\\t
和空格的混合,我们可以使用以下POSIX类[:blank:]
来匹配这2个字符。
Command: 命令:
sed -i.bak '/^[[:blank:]]*rotate[[:blank:]]\+[0-9]\+[[:blank:]]*$/{s@^\([[:blank:]]*\)@\1olddir /var/log/oldlog\n\1@}' input_file
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.