我想在符合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
因此模式可能具有上述条件。
答案 0 :(得分:2)
如果您可以接受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
分配给其他行。s/pattern/replacement/
运算符用于添加行。^
字符是一个锚点,用于匹配行的开头。否则,该模式可能与WHEN
条件内的关键字匹配。[\s\S]
表达式是一个习惯用法,用于匹配包括换行符在内的所有字符。+?
指定最短的匹配项。$&
是一个特殊变量,用于保存最后一个模式匹配所匹配的字符串。通过使用此变量,我们可以将以下行添加到指定的模式。mg
是一个告诉Perl我们正在处理多行文本并查找模式的多次出现的选项。如果您不熟悉Perl,脚本可能看起来很模糊,但是您可以从修改代码开始,然后看看会发生什么。
希望这会有所帮助。
答案 1 :(得分:1)
使用Perl One衬纸
> 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;
>
答案 2 :(得分:0)
您必须寻找一种提出简单问题的方法。
我将您的要求翻译成“在每个;
之后添加一行,但以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