简体   繁体   English

Sed在模式上多次插入行

[英]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的行,后跟空格和整数
  • when 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.

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