替换两个特定行内的内容

替换两个特定行内的内容

如何从命令行替换<!-- Analytics code start -->和之间<!-- Analytics code end -->的内容index.html

<html>
...

<!-- Analytics code start -->
...
<!-- Analytics code end -->
</body>
</html>

通过文件的内容,比如说myanalytics.txt

注意:我想通过命令行来执行此操作,因为我需要对许多文件执行此操作。

答案1

解决方案awk可能是:

awk '/Analytics code start/ { t=1; print; system("cat myanalytics.txt") } 
     /Analytics code end/   { t=0 } 
     t==0 { print } ' index.html

(我缩进代码以增加可读性,但它很容易成为一行)

简要说明:

  • t==0总是打印当前行时
  • 如果当前行与"Analytics code start"设置匹配t==1,则打印当前行和所需的文件system("cat myanalytics.txt")
  • Nowt等于1,因此永远不会打印当前行,但当当前行匹配 时"Analytics code end"t会再次设置为0,因此从现在开始打印当前行。

笔记:

这不会编辑您的文件index.html。要修改index.html您可以:

  • 将输出重定向awk到临时文件,然后使用类似mv或的命令cp

  • sponge从包中使用moreutils,如下:

    awk '[.. commands like above ..]' index.html | sponge index.html
    

答案2

根据您的情况,您可以按以下方式执行此操作:

#!/bin/sh

SOURCE=index.html
if ! test -f "$SOURCE"; then
    echo source is missing >&2
    exit 1
fi

headLimit=`grep -n '<!-- Analytics code start -->' "$SOURCE" | cut -d: -f1`
tailLimit=`grep -n '<!-- Analytics code end -->' "$SOURCE" | cut -d: -f1`
linennr=`awk '{}END{print NR + 1}' $SOURCE`

if ! test "$headLimit" -gt 0 -a "$tailLimit" -gt 0 >/dev/null; then
    echo something is wrong >&2
    exit 2
fi
(
    head -n$headLimit "$SOURCE"
    echo "the stuff I want to inject in place of my analytics code"
    tail -n`expr $linennr - $tailLimit` "$SOURCE"
) >"$SOURCE.new"

if test -s "$SOURCE.new"; then
    mv "$SOURCE" "$SOURCE.old"
    mv "$SOURCE.new" "$SOURCE"
fi

exit 0

请注意,任何ed基于解决方案的解决方案都将允许实际替换文件内的内容,而不是生成替换文件,...这可以说更干净。

答案3

我想这也许有用

sed -rn '/<!-- Analytics code start -->/{ 
           p; :X n; /<!-- Analytics code end -->/{p;b}; bX
        }; p' 

相关内容