1

SQLスキーマ定義ファイルのgit diffからの出力が与えられると、更新スクリプトと元に戻すスクリプトを作成できる単純なbashscriptを作成しようとしています。したがって、次のような入力があります。

 create table xxx
 (
-       aaa numeric(18) primary key,
-       bbb numeric(18) not null,
-       ccc numeric(18) not null,
+       aaa INT UNSIGNED AUTO_INCREMENT primary key,
+       AlarmId INT UNSIGNED not null,
+       ccc INT UNSIGNED not null,
        ddd smallint not null,
        eee varchar(2),
        fff varchar(2),
    )

更新スクリプトを作成したいとしましょう。すべてのcreateステートメントをalter's に変更し、不要な行をすべて取り除き、最後に '+' マークをchangeステートメント (mysql スクリプト) に置き換えます。私はそうするのが好きです:

sed "s/^\s*create/ALTER/g" < $infile | sed "/^\s\|@/d" | sed "/^-/d" | sed "s/^+\s*\(\`\?\w\+\`\?\)/\tCHANGE \1 \1/g"

だから私は最終的にこのようなものを得る:

ALTER table xxx
        CHANGE aaa aaa INT UNSIGNED AUTO_INCREMENT primary key,
        CHANGE bbb bbb INT UNSIGNED not null,
        CHANGE ccc ccc INT UNSIGNED not null,
        CHANGE ddd ddd smallint not null,
ALTER table yyy
        CHANGE aaa aaa INT UNSIGNED primary key,
        CHANGE bbb bbb smallint not null,
        CHANGE ccc ccc smallint not null,
        CHANGE ddd ddd INT UNSIGNED not null,
        CHANGE eee eee varchar(1024) not null
ALTER table zzz
(and so on)

最後に行う必要があるのは、各ステートメントをコロンで完了することです。基本的に、各ALTERステートメント (または EOF) を検索し、その上の行の末尾にコロンを追加する必要があります (既存のコンマを置き換える可能性があります)。sコマンドを使用してvimで実行できました:

%s/\(,\)\=\_s\+\(ALTER.*\|\%$\)/;\r\2

しかし、これを sed 構文に変換できませんでした。sed に複数行のパターンを受け入れるように強制するのは難しい仕事のようです。だから - 誰でもこれを行う方法を教えてもらえますか? sed だけが選択肢ではないと思います。それは私の最初の選択でした(見た目ほど最高ではありません:))おそらく、すぐに使えるソリューションがいくつかあり、車輪を再発明しているだけですか?

4

2 に答える 2

2

興味深いアプローチ (そして壊れやすい - 同じ行に複数の列を配置する変更を想像してみてください)。Perl はセミコロンの助けになります:

 perl -0777 -pe 's/[,\s]+ALTER/;\nALTER/g;
                 s/$/;/' < input > output
  • -0777ファイル全体を「丸呑み」します(行ごとに読み取るのではなく)
  • -p読み取ったものを処理後に出力します
  • [,\s]+空白とカンマに一致します。少なくとも 1 つのそのような文字が必要です (これにより、最初の ALTER の前にセミコロンが挿入されなくなります)。
  • 2 番目の置換は、最後のセミコロンを追加します。
于 2015-10-22T08:14:19.517 に答える
0
sed -n '
   /^[[:blank:]]*create/ {
      s//ALTER/
      H
      b
      }

   /^+\([[:blank:]]*\)\([^[:blank:]]\{1,\}\)/ {
      s//\1CHANGE \2 \2/
      H
      }
   $ !b

   x
   s/,\(\nALTER\)/;\1/g
   s/.\(.*\),$/\1;/p
   ' YourFile

すべての(いくつかの)行を一緒に操作するには、保持バッファを使用する必要があります(アクションxHここ)

于 2015-10-22T09:59:39.133 に答える