Как я могу добавить текст после некоторой последовательности текста, если эта последовательность соответствует определенным критериям с помощью сценария Shell? - PullRequest
0 голосов
/ 25 октября 2018

Я хочу добавить оператор сразу после текста, соответствующего условиям, указанным в сценарии оболочки.

Ниже приведен пример файла (файл 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;' temp.sql

Так что шаблон может иметь условия, упомянутые выше.

Ответы [ 3 ]

0 голосов
/ 25 октября 2018

Использование Perl One liner

> export row='AFFECTED_ROWS := AFFECTED_ROWS + SQL%ROWCOUNT;'
> perl -ne 'BEGIN {$x=qx(cat ora_sql.txt);$x=~s/\b(UPDATE|DELETE|INSERT|MERGE)\b(.+?);/$&\n$ENV{row}/gms;print"$x"; exit }'
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;

>
0 голосов
/ 01 ноября 2018

Вы должны искать способ задать простой вопрос.
Я перевел ваши требования в "Добавить строку после каждого ;, за исключением строк, начинающихся с AFFECTED_ROWS и end.

Решение будет использовать /^(AFFECTED_ROWS|end)/ для сопоставления двух исключений. Восклицательный знак говорит, что sed не должен выполнять замену при обнаружении исключения.

sed -r '/^(AFFECTED_ROWS|end)/ !s/;/;\nAFFECTED_ROWS := AFFECTED_ROWS + SQL%ROWCOUNT;/' temp.sql

Когда вы собираетесьвведите значения с помощью ;, вышеупомянутое решение не будет выполнено. Когда ; для сопоставления является последним символом в строке, команда будет

sed -r '/^(AFFECTED_ROWS|end)/ !s/;$/;\nAFFECTED_ROWS := AFFECTED_ROWS + SQL%ROWCOUNT;/' temp.sql
0 голосов
/ 25 октября 2018

Если Perl приемлем для вас, вам будет легко делать то, что вы хотите, потому что Perl хорош в обработке многострочных регулярных выражений.Тогда как насчет:

perl -e '
while (<>) {
    $text .= $_;
}
$add = "\nAFFECTED_ROWS := AFFECTED_ROWS + SQL%ROWCOUNT;";

$text =~ s/^UPDATE[\s\S]+?SET[\s\S]+?;/$&$add/mg;
$text =~ s/^DELETE[\s\S]+?FROM[\s\S]+?;/$&$add/mg;
$text =~ s/^INSERT[\s\S]+?INTO[\s\S]+?;/$&$add/mg;
$text =~ s/^MERGE[\s\S]+?INTO[\s\S]+?(WHEN MATCHED THEN|WHEN NOT MATCHED)[\s\S]+?(UPDATE|INSERT|DELETE)[\s\S]+?;/$&$add/mg;

print $text;
' inputfile

Пояснения

  • Прежде всего, все строки превращаются в переменную $text, включая символы новой строки.
  • Мы присваиваем переменную $add дополнительной строке.
  • Затем мы начинаем добавлять строку в шаблон, соответствующую любому из условий.
  • Оператор Perl s/pattern/replacement/работает для добавления строки.
  • Символ ^ является якорем, совпадающим с началом строки.В противном случае шаблон может совпадать с ключевыми словами в условиях WHEN.
  • Выражение [\s\S] - это идиома, соответствующая всем символам, включая символы новой строки.
  • +? указывает самое короткое соответствие.
  • $& - это специальная переменная для хранения строки, совпадающей с последним совпадением шаблона.Используя эту переменную, мы можем добавить строку, следующую за указанным шаблоном.
  • mg рядом с крайней правой косой чертой - это опция, которая сообщает Perl, что мы обрабатываем многострочный текст, и чтобы найти множественное вхождениеthe pattern.

Сценарий может выглядеть запутанным, если вы не знакомы с Perl, но вы можете начать с изменения кода и посмотреть, что произойдет.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...