使用 awk 提取一对括号之间的文本
我们有一个包含函数定义的 SQL 文件。我们想要读取此文件并准备另一个 SQL 文件,其中包含第一个 SQL 文件中所有函数的所有 drop DDL 语句。
例如,第一个 sql 的内容如下:
CREATE OR REPLACE FUNCTION folder_cycle_check (folder_key INTEGER, new_parent_folder_key INTEGER) RETURNS VOID AS $procedure$
DECLARE
parent_of_parent INTEGER;
BEGIN
IF folder_key = new_parent_folder_key THEN
RAISE EXCEPTION 'Illegal cycle detected',new_parent_folder_key;
END IF;
SELECT INTO parent_of_parent (SELECT parent_folder_key FROM folder where folder_key = new_parent_folder_key);
IF new_parent_folder_key IS NOT NULL THEN
PERFORM folder_cycle_check(folder_key, parent_of_parent);
END IF;
END; $procedure$
LANGUAGE plpgsql;
现在我想将目标 SQL 文件创建为:
DROP FUNCTION folder_cycle_check((folder_key INTEGER, new_parent_folder_key INTEGER)
为了实现此目的,我有一个“genDrop.txt”文件,我将其与第一个 SQL 文件一起传递给 awk.exe 命令。 “genDrop.txt”的问题在于它仅生成带有 drop 语句的目标 SQL 文件:
DROP FUNCTION folder_cycle_check
which is not useful because PostgreSQL wants like this:
DROP FUNCTION folder_cycle_check(folder_key INTEGER, new_parent_folder_key INTEGER)
有人可以帮助我吗?我是 awk 编程的新手。 仅供参考,“genDrop.txt”是这样的:
#######################################################################
# AWK program to generate drop statements from create table, procedure, and view statements
############################################################################
function dropit(objtype, objname, rulename)
{
# l[lines++] = "DROP " objtype " " objname " -- Line " NR ", Rule " rulename;
l[lines++] = "DROP " objtype " " objname
next
}
function dropitpg(objtype, objname, funcargs, rulename)
{
# l[lines++] = "DROP " objtype " " objname " -- Line " NR ", Rule " rulename;
l[lines++] = "DROP " objtype " " objname " " funcargs
next
}
BEGIN { FS="[ (;]*" }
# trim the line
{$2 = $2 }
# "grab creates"
/^ +[Cc][Rr][Ee][Aa][Tt][Ee] *[Pp][Rr][Oo][Cc]/ {dropit($3, $4, "CPs") }
/^[Cc][Rr][Ee][Aa][Tt][Ee] *[Pp][Rr][Oo][Cc]/ {dropit($2, $3, "CP") }
/^ +[Cc][Rr][Ee][Aa][Tt][Ee] *[Oo][Rr] *[Rr][Ee][Pp][Ll][Aa][Cc][Ee] *[Pp][Rr][Oo][Cc]/ {dropit($5, $6, "CPs") }
/[Cc][Rr][Ee][Aa][Tt][Ee] *[Oo][Rr] *[Rr][Ee][Pp][Ll][Aa][Cc][Ee] *[Pp][Rr][Oo][Cc]/ {dropit($4, $5, "CP") }
/^ +[Cc][Rr][Ee][Aa][Tt][Ee] *[Vv][Ii][Ee][Ww]/ {dropit($3, $4, "CVs") }
/[Cc][Rr][Ee][Aa][Tt][Ee] *[Vv][Ii][Ee][Ww]/ {dropit($2, $3, "CV") }
/^ +[Cc][Rr][Ee][Aa][Tt][Ee] *[Oo][Rr] *[Rr][Ee][Pp][Ll][Aa][Cc][Ee] *[Vv][Ii][Ee][Ww]/ {dropit($5, $6, "CRVs") }
/[Cc][Rr][Ee][Aa][Tt][Ee] *[Oo][Rr] *[Rr][Ee][Pp][Ll][Aa][Cc][Ee] *[Vv][Ii][Ee][Ww]/ {dropit($4, $5, "CRV") }
/^ +[Cc][Rr][Ee][Aa][Tt][Ee] *[Tt][Aa][Bb][Ll][Ee]/ {dropit($3, $4, "CTs") }
/^[Cc][Rr][Ee][Aa][Tt][Ee] *[Tt][Aa][Bb][Ll][Ee]/ {dropit($2, $3, "CT") }
/^ +[Cc][Rr][Ee][Aa][Tt][Ee] *[Ss][Ee][Qq][Uu][Ee][Nn][Cc][Ee]/ {dropit($3, $4, "CSs") }
/[Cc][Rr][Ee][Aa][Tt][Ee] *[Ss][Ee][Qq][Uu][Ee][Nn][Cc][Ee]/ {dropit($2, $3, "CS") }
/^ +[Cc][Rr][Ee][Aa][Tt][Ee] *[Ff][Uu][Nn][Cc][Tt][Ii][Oo][Nn]/ {dropit($3, $4, "CSs") }
/[Cc][Rr][Ee][Aa][Tt][Ee] *[Ff][Uu][Nn][Cc][Tt][Ii][Oo][Nn]/ {dropit($2, $3, "CS") }
END{
print "-- Beginning " lines " drop statements"
for (i = lines - 1; i >= 0; --i) {
print l[i]
print EOS
print ""
}
print "-- End of " lines " drop statements"
}
BEGIN { FS="[ ;]*" }
/^ +[Cc][Rr][Ee][Aa][Tt][Ee] *[Oo][Rr] *[Rr][Ee][Pp][Ll][Aa][Cc][Ee] *[Ff][Uu][Nn][Cc][Tt][Ii][Oo][Nn]/ {dropitpg($5, $7, "CSs") }
/[Cc][Rr][Ee][Aa][Tt][Ee] *[Oo][Rr] *[Rr][Ee][Pp][Ll][Aa][Cc][Ee] *[Ff][Uu][Nn][Cc][Tt][Ii][Oo][Nn]/ {sed -nr "s/\s*\[([^\]+)\]/\1/p" }
END{
print "-- Beginning " lines " drop statements"
for (i = lines - 1; i >= 0; --i) {
print l[i]
print EOS
print ""
}
print "-- End of " lines " drop statements"
}
We have an SQL file with function definitions. We want to read this file and prepare another SQL file with all the drop DDL statements for all the functions in the first SQL file.
For example the first sql has the content like this:
CREATE OR REPLACE FUNCTION folder_cycle_check (folder_key INTEGER, new_parent_folder_key INTEGER) RETURNS VOID AS $procedure$
DECLARE
parent_of_parent INTEGER;
BEGIN
IF folder_key = new_parent_folder_key THEN
RAISE EXCEPTION 'Illegal cycle detected',new_parent_folder_key;
END IF;
SELECT INTO parent_of_parent (SELECT parent_folder_key FROM folder where folder_key = new_parent_folder_key);
IF new_parent_folder_key IS NOT NULL THEN
PERFORM folder_cycle_check(folder_key, parent_of_parent);
END IF;
END; $procedure$
LANGUAGE plpgsql;
Now I want to create the target SQL file as:
DROP FUNCTION folder_cycle_check((folder_key INTEGER, new_parent_folder_key INTEGER)
For this to achieve I have a "genDrop.txt" file which I pass to awk.exe command along with the first SQL file. The problem with the "genDrop.txt" is that it is only generating the target SQL file with drop statements as:
DROP FUNCTION folder_cycle_check
which is not useful because PostgreSQL wants like this:
DROP FUNCTION folder_cycle_check(folder_key INTEGER, new_parent_folder_key INTEGER)
Can anybody help me? I am new to the awk programming.
FYI, the "genDrop.txt" is this:
#######################################################################
# AWK program to generate drop statements from create table, procedure, and view statements
############################################################################
function dropit(objtype, objname, rulename)
{
# l[lines++] = "DROP " objtype " " objname " -- Line " NR ", Rule " rulename;
l[lines++] = "DROP " objtype " " objname
next
}
function dropitpg(objtype, objname, funcargs, rulename)
{
# l[lines++] = "DROP " objtype " " objname " -- Line " NR ", Rule " rulename;
l[lines++] = "DROP " objtype " " objname " " funcargs
next
}
BEGIN { FS="[ (;]*" }
# trim the line
{$2 = $2 }
# "grab creates"
/^ +[Cc][Rr][Ee][Aa][Tt][Ee] *[Pp][Rr][Oo][Cc]/ {dropit($3, $4, "CPs") }
/^[Cc][Rr][Ee][Aa][Tt][Ee] *[Pp][Rr][Oo][Cc]/ {dropit($2, $3, "CP") }
/^ +[Cc][Rr][Ee][Aa][Tt][Ee] *[Oo][Rr] *[Rr][Ee][Pp][Ll][Aa][Cc][Ee] *[Pp][Rr][Oo][Cc]/ {dropit($5, $6, "CPs") }
/[Cc][Rr][Ee][Aa][Tt][Ee] *[Oo][Rr] *[Rr][Ee][Pp][Ll][Aa][Cc][Ee] *[Pp][Rr][Oo][Cc]/ {dropit($4, $5, "CP") }
/^ +[Cc][Rr][Ee][Aa][Tt][Ee] *[Vv][Ii][Ee][Ww]/ {dropit($3, $4, "CVs") }
/[Cc][Rr][Ee][Aa][Tt][Ee] *[Vv][Ii][Ee][Ww]/ {dropit($2, $3, "CV") }
/^ +[Cc][Rr][Ee][Aa][Tt][Ee] *[Oo][Rr] *[Rr][Ee][Pp][Ll][Aa][Cc][Ee] *[Vv][Ii][Ee][Ww]/ {dropit($5, $6, "CRVs") }
/[Cc][Rr][Ee][Aa][Tt][Ee] *[Oo][Rr] *[Rr][Ee][Pp][Ll][Aa][Cc][Ee] *[Vv][Ii][Ee][Ww]/ {dropit($4, $5, "CRV") }
/^ +[Cc][Rr][Ee][Aa][Tt][Ee] *[Tt][Aa][Bb][Ll][Ee]/ {dropit($3, $4, "CTs") }
/^[Cc][Rr][Ee][Aa][Tt][Ee] *[Tt][Aa][Bb][Ll][Ee]/ {dropit($2, $3, "CT") }
/^ +[Cc][Rr][Ee][Aa][Tt][Ee] *[Ss][Ee][Qq][Uu][Ee][Nn][Cc][Ee]/ {dropit($3, $4, "CSs") }
/[Cc][Rr][Ee][Aa][Tt][Ee] *[Ss][Ee][Qq][Uu][Ee][Nn][Cc][Ee]/ {dropit($2, $3, "CS") }
/^ +[Cc][Rr][Ee][Aa][Tt][Ee] *[Ff][Uu][Nn][Cc][Tt][Ii][Oo][Nn]/ {dropit($3, $4, "CSs") }
/[Cc][Rr][Ee][Aa][Tt][Ee] *[Ff][Uu][Nn][Cc][Tt][Ii][Oo][Nn]/ {dropit($2, $3, "CS") }
END{
print "-- Beginning " lines " drop statements"
for (i = lines - 1; i >= 0; --i) {
print l[i]
print EOS
print ""
}
print "-- End of " lines " drop statements"
}
BEGIN { FS="[ ;]*" }
/^ +[Cc][Rr][Ee][Aa][Tt][Ee] *[Oo][Rr] *[Rr][Ee][Pp][Ll][Aa][Cc][Ee] *[Ff][Uu][Nn][Cc][Tt][Ii][Oo][Nn]/ {dropitpg($5, $7, "CSs") }
/[Cc][Rr][Ee][Aa][Tt][Ee] *[Oo][Rr] *[Rr][Ee][Pp][Ll][Aa][Cc][Ee] *[Ff][Uu][Nn][Cc][Tt][Ii][Oo][Nn]/ {sed -nr "s/\s*\[([^\]+)\]/\1/p" }
END{
print "-- Beginning " lines " drop statements"
for (i = lines - 1; i >= 0; --i) {
print l[i]
print EOS
print ""
}
print "-- End of " lines " drop statements"
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您的示例输出(减去额外的 open-paren)就是您所需要的,那么我认为您的脚本太过了。这个怎么样?
请务必
chmod 755 genDrop.awk
sample run
(我将示例输入的第一行更改为 )
示例运行
另外,将 awk 脚本命名为 genDrop.txt 无助于传达您的意图,当然您的意思是 genDrop.awk
If your example output (minus the extra open-paren) is all you need then I think your script is over-kill. How about this?
be sure to
chmod 755 genDrop.awk
sample run
(I changed the first line of your sample input to )
sample run
Also, naming your awk script as genDrop.txt has not helped in communicating what your intention is, surely you mean genDrop.awk