Substituir conteúdo dentro de duas linhas específicas

2

Como substituir, na linha de comando, o conteúdo entre <!-- Analytics code start --> e <!-- Analytics code end --> de index.html :

<html>
...

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

pelo conteúdo de um arquivo, digamos myanalytics.txt ?

Nota: Eu quero fazer isso por linha de comando porque eu preciso fazer isso para muitos arquivos.

    
por Basj 03.01.2017 / 19:08

3 respostas

2

Uma solução com awk poderia ser:

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

(Eu indentei o código para aumentar a legibilidade, mas pode ser facilmente oneline)

Brevemente explicação:

  • Quando t==0 sempre imprime a linha atual
  • Se a linha atual corresponder a "Analytics code start" set t==1 e, em seguida, imprimir a linha atual e o arquivo desejado com system("cat myanalytics.txt")
  • Agora, t é igual a 1 , portanto a linha atual nunca é impressa, mas quando a linha atual corresponde a "Analytics code end" , t é definido como 0 novamente, imprima a linha atual a partir de agora .

Nota:

Isso não editará seu arquivo index.html . Para modificar index.html , você pode:

  • redirecione a saída de awk para um arquivo temporário e use um comando como mv ou cp

  • use sponge do pacote moreutils , da seguinte forma:

    awk '[.. commands like above ..]' index.html | sponge index.html
    
por 03.01.2017 / 23:59
0

Dada a sua situação, veja como você pode fazer isso:

#!/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

Observe que qualquer solução baseada em ed permitiria substituir o arquivo em vez de gerar um substituto, ... O que seria indiscutivelmente mais limpo.

    
por 03.01.2017 / 21:51
0

acho que isso talvez funcione

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