2つの特定の行内で内容を置き換える

2つの特定の行内で内容を置き換える

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

(読みやすくするためにコードをインデントしましたが、簡単に1行にすることもできます)

簡単な説明:

  • 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

  • spongemoreutils次のようにパッケージで使用してください。

    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' 

関連情報