如何用命令 sed 替换文件中某些特定内容(各行)?

如何用命令 sed 替换文件中某些特定内容(各行)?

我想知道如何替换这个:

.otros{
   position: fixed;
   top: 116px;
   z-index: 100;
   left: 0;
}

这样:

.otros{
   position: fixed;
   top: 70%;
   z-index: 100;
   left: 0;
} 

文件内容类似如下:

.social a:not(:hover){
    width: 70px;
    -webkit-transition: 600ms;
    -o-transition: 600ms;
    -ms-transition: 600ms;
}
.social div a:not(:hover){
    width:200%;
}
.otros{
    position: fixed;
    top: 116px;
    z-index: 100;
    left: 0;
}

该命令不起作用:

sed 's/.otros{\ntop*:*;\n}/.otros{\ntop:70%;\n}/g' estilos.css

结果是:

.social a:not(:hover){
    width: 70px;
    -webkit-transition: 600ms;
    -o-transition: 600ms;
    -ms-transition: 600ms;
}
.social div a:not(:hover){
    width:200%;
}
.otros{
    position: fixed;
    top: 116px;
    z-index: 100;
    left: 0;
}

如何替换特定的线条?

答案1

Sed 替换默认针对单行进行操作;要在多行上下文中执行匹配,您需要使用命令N将其他行读入模式空间。例如:

$ sed '/\.otros{/ {N;N;s/top: 116px/top: 70%/}' estilos.css 
  .social a:not(:hover){
    width: 70px;
    -webkit-transition: 600ms;
    -o-transition: 600ms;
    -ms-transition: 600ms;
  }
  .social div a:not(:hover){
    width:200%;
  }
  .otros{
    position: fixed;
    top: 70%;
    z-index: 100;
    left: 0;
  }

答案2

下列Perl脚本匹配.otros{行与行之间的所有内容,并将该行top:替换为:top:top: 70%;

perl -pe 's/(?!\.otros\{[\w\d\s:;\-%]*)top:.*/top: 70%;/' estilos.css

.otros{如果线与线之间的线条top:包含除以下内容之外的其他内容:

  • 小写字母、大写字母、下划线 ( \w)
  • 数字 ( \d)
  • 空格 ( \s)
  • 冒号 (:
  • 分号 ( ;)
  • 破折号 ( \-)
  • 百分号 ( %)

只需将其添加在方括号 ( []) 之间即可。

结果是:

.social a:not(:hover){
    width: 70px;
    -webkit-transition: 600ms;
    -o-transition: 600ms;
    -ms-transition: 600ms;
}
.social div a:not(:hover){
    width:200%;
}
.otros{
    position: fixed;
    top: 70%;
    z-index: 100;
    left: 0;
}

笔记:此脚本不仅会替换top: 116px;,还会替换内top:( top:.*)后面的所有内容.otros。例如,它还会替换top: 55px;top: 90%;

如果您只需要替换top: 116px;,那么命令将是这样的:

perl -pe 's/(?!\.otros\{[a-zA-Z0-9\s:;\-%]*)top: 116px;/top: 70%;/' estilos.css

相关内容