パターン別にファイルを分割

パターン別にファイルを分割

複数の仮想ホストを持つApache仮想ホストファイルをファイルごとに1つの仮想ホストに分割する簡単な方法はありますか?

あるいは、1つの仮想ホストのみを操作してgrep出力を取得できるようになります。

Bashで好む解決策です。

答え1

行の内容に基づいてファイルを分割できますcsplit。これはPOSIX コマンドしかし、GNUバージョンいくつかの便利な拡張機能があります。 GNU csplit(含まれていないLinux、Cygwin)を使用して、次から始まる各行からファイルを分割する方法は次のとおりです<VirtualHost

csplit -f 'virtualhost-' -b '%03d.conf' all-sites.conf '/^ *<VirtualHost /' '{*}'

ポータブル、これはより薄暗いです。発生回数を数える必要があり、出力ファイル名は一連の数字で終わります。

csplit -f 'virtualhost-' all-sites.conf '/^ *<VirtualHost /' "{$(($(grep -c '^ *<VirtualHost <all-sites.conf') - 1))}"

いずれにしても、最初のファイルには最初の行の前の内容がすべて含まれています<VirtualHost。行の前にコメントがある場合は、<VirtualHost次のセクションに追加されません。<VirtualHost注釈csplitが前に来るのか後に来るのかを調べるのは言うまでもなく、そうするほどスマートではありません。

コンテンツの後に出力ファイル名を指定するなど、よりクールなタスクを実行するには、awkを使用できます。 csplitユーティリティは時々便利ですが、awkは可能なすべての操作を簡単に実行できます。

awk '
  BEGIN {output_file = "preamble.conf"}
  /^ *<VirtualHost *[^ >]/ {
      output_file = "virtualhost-" sub(/ *[:>].*/, "", sub(/^ *<VirtualHost */, "", $0) ".conf";
  }
  {print >output_file}
' all-sites.conf

答え2

ここでは動作しますが、完璧ではありません。

#!/bin/bash


i=1
echo >vhost_${i}.conf
while IFS= read -r lin; do
        case $lin in 
        \<VirtualHost*\>)
                true
        ;;
        esac

        echo "$lin" >>vhost_${i}.conf 

        case $lin in 
        \</VirtualHost\>)
            i=$((i+1))
            echo >>vhost_${i}.conf
        ;;
        esac

done

次のように、ファイルの内容をこのスクリプトにパイプする必要があります。

cat thenicefile.conf | thisscript 

thenicefile.confに仮想ホスト番号が割り当てられている可能性があります!

関連情報