シェルスクリプトの使用に関する特定の基準を満たしている場合、一連のテキストの後にテキストを追加するにはどうすればよいですか?

シェルスクリプトの使用に関する特定の基準を満たしている場合、一連のテキストの後にテキストを追加するにはどうすればよいですか?

シェルスクリプトに記載されている条件に一致するテキストの後にステートメントを追加したいと思います。

これは私のサンプルファイル(SQLファイル)です。

begin
AFFECTED_ROWS := 0;

UPDATE table_name
SET column1 = value1, column2 = value2, ...
WHERE condition;

DELETE FROM table_name
WHERE condition;

INSERT INTO table_name (column1, column2, column3, ...)
VALUES (value1, value2, value3, ...);

MERGE INTO employees e
    USING hr_records h
    ON (e.id = h.emp_id)
  WHEN MATCHED THEN
    UPDATE SET e.address = h.address
  WHEN NOT MATCHED THEN
    INSERT (id, address)
    VALUES (h.emp_id, h.address);
end;

次のいずれかのテキストが順番に表示されたら、このファイルをインポートして次の変換を実行します。

1: "UPDATE ... SET ...;"
2: "DELETE ... FROM ...;"
3: "INSERT ... INTO ...;"
4: "MERGE ... INTO ... [WHEN MATCHED THEN | WHEN NOT MATCHED] ... [UPDATE|INSERT|DELETE] ... ;"

セミコロンの後に1行を追加する必要があります

AFFECTED_ROWS := AFFECTED_ROWS + SQL%ROWCOUNT;

私の新しいファイルは次のとおりです。

begin
AFFECTED_ROWS := 0;

UPDATE table_name
SET column1 = value1, column2 = value2, ...
WHERE condition;
AFFECTED_ROWS := AFFECTED_ROWS + SQL%ROWCOUNT;

DELETE FROM table_name
WHERE condition;
AFFECTED_ROWS := AFFECTED_ROWS + SQL%ROWCOUNT;

INSERT INTO table_name (column1, column2, column3, ...)
VALUES (value1, value2, value3, ...);
AFFECTED_ROWS := AFFECTED_ROWS + SQL%ROWCOUNT;

MERGE INTO employees e
    USING hr_records h
    ON (e.id = h.emp_id)
  WHEN MATCHED THEN
    UPDATE SET e.address = h.address
  WHEN NOT MATCHED THEN
    INSERT (id, address)
    VALUES (h.emp_id, h.address);
AFFECTED_ROWS := AFFECTED_ROWS + SQL%ROWCOUNT;

end;

PLSQLのスコープでメソッドを見つけて実装しようとしましたが、行に影響を与えない可能性がある一般的なメソッドが見つからず、テキスト解析を考えましたが、awkやsedについてはわかりません。

今私は次のことをしようとしています。

sed '/Patterns Go Here/a AFFECTED_ROWS := AFFECTED_ROWS + SQL%ROWCOUNT;' 一時 SQL

したがって、パターンは上記の条件を持つことができます。

答え1

sedの代わりにperlを使用し、入力レコード区切り文字 - $ / (IRS)特殊変数を使用して、改行ではなくセミコロンのある行を処理することで問題を解決しました。

IRSの変更をサポートするすべての言語が機能するはずです(純粋なbashを使用して可能かもしれませんが、IFS=';'まだ見ていません)。

この例では、Perlはレコード区切り文字が入力されるまでバッファをロードし、すべてを単一行として処理します。区切り文字の内容を変更すると、一度に1行ではなく一度に1つのステートメントを処理できます。その後、関心のある問い合わせパターンを照合して印刷する前に、影響を受ける行をその行に論理的に追加できます。

$ cat test.sql
SELECT non-matching-statement FROM table;

MERGE INTO employees e
    USING hr_records h
    ON (e.id = h.emp_id)
  WHEN MATCHED THEN
    UPDATE SET e.address = h.address
  WHEN NOT MATCHED THEN
    INSERT (id, address)
    VALUES (h.emp_id, h.address);

SELECT another-non-matching-statement FROM table;

end;

$ cat test.sql | perl -pe 'BEGIN{$/=";"} m/MERGE INTO .*/ && ($_ .=  "\nAFFECTED_ROWS := AFFECTED_ROWS + SQL %ROWCOUNT;")'
SELECT non-matching-statement FROM table;

MERGE INTO employees e
    USING hr_records h
    ON (e.id = h.emp_id)
  WHEN MATCHED THEN
    UPDATE SET e.address = h.address
  WHEN NOT MATCHED THEN
    INSERT (id, address)
    VALUES (h.emp_id, h.address);
AFFECTED_ROWS := AFFECTED_ROWS + SQL%ROWCOUNT;

SELECT another-non-matching-statement FROM table;

end;

$

Perl速記をあまり使用しない場合は、次のようにできます。

perl -e '$/=";"; foreach $statement (<>){ print $statement; $statement =~ m/(MERGE INTO .*)|(DELETE FROM)/i && print "\nAFFECTED_ROWS := AFFECTED_ROWS + SQL%ROWCOUNT;" }'

たとえば、

cat test.sql | perl -e '$/=";"; foreach $statement (<>){ print $statement; $statement =~ m/(MERGE INTO .*)|(DELETE FROM)/i && print "\nAFFECTED_ROWS := AFFECTED_ROWS + SQL%ROWCOUNT;" }'
SELECT non-matching-statement FROM table;

MERGE INTO employees e
    USING hr_records h
    ON (e.id = h.emp_id)
  WHEN MATCHED THEN
    UPDATE SET e.address = h.address
  WHEN NOT MATCHED THEN
    INSERT (id, address)
    VALUES (h.emp_id, h.address);
AFFECTED_ROWS := AFFECTED_ROWS + SQL%ROWCOUNT;

SELECT another-non-matching-statement FROM table;

DELETE FROM truncate_me;
AFFECTED_ROWS := AFFECTED_ROWS + SQL%ROWCOUNT;

end;
$

関連情報