2

クエリを含むファイルがあり、各クエリは「;」で終わります。「COMMIT;BEGIN;」を追加したいです。100クエリごと。クエリは 1 行以上かかる場合があります。

例えば:


    INSERT INTO table
    VALUES(...);
    DELETE FROM table WHERE ...;
    UPDATE table
    SET ...;

だから私は100個ごとに置き換えたい ";" 「COMMIT;BEGIN;」で (ファイルの先頭に BEGIN を追加し、最後に何かを行う必要があることはわかっていますが、簡単です)

シェルスクリプトでそれを行う必要がありますが、私は Linux の専門家ではありません。sed と awk のどちらを使用する方がよいでしょうか (また、ファイルサイズは 4GB のように巨大になる可能性があります)。これらのコマンドの基本は知っていますが、ここでやりたいことができるかどうかはわかりません...

ありがとう!

4

4 に答える 4

1

セミコロンを置き換えないことをお勧めします。代わりに、すべてのコマンドを「解析」し、コミットしたい一連のコマンドを配置BEGINします。COMMITこれは、sed を使用するとかなり簡単です。このファイルがある場合:

$ cat my.sql 
INSERT INTO table VALUES (1);
INSERT INTO table VALUES (2);
INSERT INTO table VALUES (3);
INSERT INTO table VALUES (4);
INSERT INTO table VALUES (5);
INSERT INTO table VALUES (6);
INSERT INTO table VALUES (7);
INSERT INTO table VALUES (8);
INSERT INTO table VALUES (9);
INSERT INTO table VALUES (10);

このコマンドを実行するだけです:

$ sed -n 'H;${x;s/\([^;]*;\)\{,3\}/BEGIN;&\nCOMMIT;\n\n/g;p}' my.sql 
BEGIN;
INSERT INTO table VALUES (1);
INSERT INTO table VALUES (2);
INSERT INTO table VALUES (3);
COMMIT;

BEGIN;
INSERT INTO table VALUES (4);
INSERT INTO table VALUES (5);
INSERT INTO table VALUES (6);
COMMIT;

BEGIN;
INSERT INTO table VALUES (7);
INSERT INTO table VALUES (8);
INSERT INTO table VALUES (9);
COMMIT;

BEGIN;
INSERT INTO table VALUES (10);
COMMIT;

(ここでは、わかりやすくするためにブロックのサイズとして 3 を使用しています。100 コマンドのブロックを「受け入れる」場合は、に置き換え\{,3\}ます \{,100\})

それは何をするためのものか?

  • まず、 で行の印刷を禁止し-nます。sed は、明示的に印刷するように命令した場合にのみ、行を印刷します。

  • ここで、行ごとに、行をホールド スペースに追加しますH

  • 最後の行 (アドレス$) で、コマンドのブロックを実行します (で始まり、{で終わります})。最初のコマンドxは、ホールド スペース (現在はすべてのファイルが含まれています) とパターン スペースの内容を交換します。

  • s///この後、 n (0 < n <= 3) の一連の文字 ( ではない)に置き換え、;続い;て string BEGIN;、一致するコマンドのブロック ( で表される&)、および文字列\nCOMMIT;\n\n(読みやすくするために改行を使用) に置き換えます。

  • 最後に、パターン空間の内容を で出力しpます。

于 2012-06-05T17:30:36.313 に答える
1

が行末にあることを保証できる場合;、または複数の を含む行をあまり気にしない場合;、簡単な解決策 (テストされていません) は次のとおりです。

awk '/;/{ count+=1 } {print} count==100 { print "COMMIT; BEGIN"; count=0 }'
于 2012-06-05T17:17:40.737 に答える
0

This might work for you (GNU sed);

sed ':a;$!{N;ba};s/^\([^;]*\(;[^\n][^;]*\)*;\s*$\)\{100\}/&\nCOMMIT;BEGIN;/mg' file
于 2012-06-05T20:59:24.613 に答える
0

セミコロンが行末にある場合:

awk '{print} /;$/ && ! (count++%100) {print "COMMIT; BEGIN;"}' inputfile

正確に 100 個のセミコロンを数えることが重要であり、それらが行のどこにでもある可能性がある場合は、それを行うことができますが、少し複雑になります。

于 2012-06-05T17:27:45.020 に答える