sed: 構成ブロックの複数行の置換

sed: 構成ブロックの複数行の置換

デフォルトでは、次の構成ファイルがあります。

(...content...)
# BEGIN DYNAMIC BLOCK - DO NOT EDIT MANUALLY
(... more content ...)
# END DYNAMIC BLOCK
(... even more content ...)

これでb​​ashでこれを使ってCONTENT=`wget -O - http://$SERVER/get_config.php`動的ブロックを置き換えました。

これで、代替操作を実行する方法と、そのブロックが存在しない場合は、ファイルの末尾にそのブロックを挿入するスクリプトを取得する方法は何ですか?

ベストアンサー1

sedを使用するには、名前付きパイプから読み取ることができます。このコードはエラーを処理しません。動的ブロックヘッダーが複数回表示されると、スクリプトはブロックされます。

CONTENT_URL="http://$SERVER/get_config.php"
tmp=$(mktemp -d)
(
  cd "$tmp"
  mkfifo dynamic_seen dynamic_content
  : >dynamic_seen & seen_pid=$!
  wget -O dynamic_content "$CONTENT_URL" & wget_pid=$!
  sed -e '/^# BEGIN DYNAMIC BLOCK - DO NOT EDIT MANUALLY$/ p' \
      -e '/^# END DYNAMIC BLOCK$/ {'
          -e p -e 'r dynamic_seen' -e 'r dynamic_content' -e '}' \
      -e '/^# BEGIN DYNAMIC BLOCK - DO NOT EDIT MANUALLY$/, /^# END DYNAMIC BLOCK$/ d'
  if ! kill $dynamic_seen 2>/dev/null; then
    # The pipe hasn't been read, so there was no dynamic block. Add one.
    echo "# BEGIN DYNAMIC BLOCK - DO NOT EDIT MANUALLY"
    cat dynamic_pipe
    echo "# END DYNAMIC BLOCK - DO NOT EDIT MANUALLY"
  fi
)
rm -rf "$tmp"

しかし、私はawkを選択します。

export CONTENT_URL="http://$SERVER/get_config.php"
awk '
    $0 == "# END DYNAMIC BLOCK - DO NOT EDIT MANUALLY" {skip=0; system("wget \"$CONTENT_URL\""); substituted=1}
    !skip {print}
    $0 == "# BEGIN DYNAMIC BLOCK - DO NOT EDIT MANUALLY" {skip=1}
    END {
         if (!substituted) {
            print "# BEGIN DYNAMIC BLOCK - DO NOT EDIT MANUALLY";
            system("wget \"$CONTENT_URL\"");
            print "# END DYNAMIC BLOCK - DO NOT EDIT MANUALLY";
        }
    }
'

おすすめ記事