【发布时间】:2011-02-24 14:44:32
【问题描述】:
我有一个包含很多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; 结尾的行。
我已经研究了前瞻/后瞻,但 sed 不支持它们。它们似乎在 super-sed 中受支持,但我目前使用的是 Cygwin(这里必须使用 Windows...),并且它似乎在软件包列表中不可用。
有没有办法强制 sed 只考虑特定的行?
在应用 sed 之前,我考虑过通过 grep 管道我的文件,但其他行随后将从输出中消失。
我是否遗漏了一些明显的东西?
如果答案很容易适用于默认的 Cygwin 安装,那就太好了。我想我可以尝试在cygwin上安装super-sed,但我想知道是否有更明显的想法
【问题讨论】:
-
鉴于您的示例,将 \w+ 替换为 [a-z]+ 会起作用,但它可能仍然对所有内容都不够选择性。
-
你在这两种情况下都是对的!我举了一个简化的例子,但我真正担心的是不小心替换了COPY语句读取的一些数据,因为那里有很多数据......
标签: regex sed cygwin grep replace