我有一个包含大量SQL语句的文件,例如:
CREATE TABLE "USER" (
"ID" INTEGER PRIMARY KEY,
"NAME" CHARACTER VARYING(50) NOT NULL,
"AGE" INTEGER NOT NULL
);
COPY "USER" (id, name, age) FROM stdin;
1 Skywalker 19
2 Kenobi 57
我希望COPY
语句中的列名称为大写且引用:
COPY "USER" ("ID", "NAME", "AGE") FROM stdin;
使用sed,我找到了以下正则表达式:
sed -r 's/([( ])(\w+)([,)])/\1"\U\2\E"\3/g'
它 替换列名,但它没有足够的选择性,并替换文件中的其他单词:
~/test]$sed -r 's/([( ])(\w+)([,)])/\1"\U\2\E"\3/g' star_wars_example
CREATE TABLE "USER" (
"ID" INTEGER PRIMARY "KEY",
"NAME" CHARACTER VARYING("50")NOT "NULL",
"AGE" INTEGER NOT NULL
);
COPY "USER" ("ID", "NAME", "AGE") FROM stdin;
1 Skywalker 19
2 Kenobi 57
为避免此问题,我希望 sed 仅将我的正则表达式应用于以COPY
开头并以FROM stdin;
结尾的行。
我已经研究过lookahead / lookbehind,但它们在sed中不受支持。它们似乎在super-sed中得到支持,但我目前正在使用Cygwin(Windows在这里是强制性的......)并且它似乎在包列表中不可用。
有没有办法强制 sed 只考虑特定的行?
在应用 sed 之前,我已经考虑通过 grep 管道我的文件,但其他行将从输出中消失。
我错过了一些明显的东西吗?
如果答案很容易适用于默认的Cygwin安装,那将会很棒。我想我可以尝试在cygwin上安装super-sed,但我想知道是否有更明显的想法
答案 0 :(得分:2)
由于我目前没有可用的sed,并且从未实际使用过分组,因此该命令可能会起作用,也可能起作用(根本不起作用)=)
尝试
sed -r '/^COPY /{ s/([( ])(\w+)([,)])/\1"\U\2\E"\3/g }'
如果我正确理解了手册,这将在以COPY
开头的任何行上执行替换。
另一种方法是使用分支。这看起来会复杂得多,但更灵活。