首页 > 解决方案 > 如果此序列与使用 Shell 脚本的某些条件匹配,我如何在某个文本序列之后添加一些文本?

问题描述

我想在与 shell 脚本中提到的条件匹配的文本之后添加一个语句。

下面是我的示例文件(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

所以模式可能有上面提到的条件。

标签: bashshellunixawksed

解决方案


如果 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 我们正在处理多行文本并查找模式的多次出现。

如果您不熟悉 Perl,该脚本可能看起来很模糊,但您可以从修改代码开始,看看会发生什么。

希望这可以帮助。


推荐阅读