2010-05-27 66 views
3

某些行我有一个包含大量的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;结尾。

我已经看过前瞻/ lookbehead,但它们不支持在sed中。它们似乎在超级sed中得到了支持,但我目前使用Cygwin(Windows在此处是强制性的......),并且它在包列表中似乎不可用。

有没有办法强制sed只考虑特定行?

我已经考虑申请管道之前我的文件通过的grep sed的,但随后其他线路将从输出消失。

我失去了一些东西明显?

如果答案很容易适用于默认的Cygwin安装,那将会很棒。我想我可以尝试在cygwin上安装super-sed,但我想知道是否有更明显的想法

+1

给出你的例子,用\ [a-z] +替换\ w +可以工作,但它可能对任何东西都不够有选择性。 – 2010-05-27 11:22:56

+0

你对这两种情况都是对的!我给出了一个简化的例子,但是我真正的担心是不小心替换了COPY语句读取的一些数据,因为那里有很多数据... – 2010-05-27 11:40:42

回答

2

由于目前我没有sed可用,并且从未实际使用过分组,命令可能会或可能无法正常工作(在所有,或按预期)=)

尝试

sed -r '/^COPY /{ s/([(])(\w+)([,)])/\1"\U\2\E"\3/g }' 

如果我正确理解说明书,这将执行上开始COPY任何线的取代。

另一种方法是使用分支。这看起来会复杂得多,但更灵活。

+0

哇,非常感谢!这工作完美无瑕。虽然这解决了我遇到的问题,但我对分支方法感到好奇:是否涉及对文件进行格式化,寻找“^ COPY”,然后将结果“分支”到sed或标准输出?如何做到这一点? (也许在另一个答案中发布,以便人们也可以投票) – 2010-05-27 12:50:30

+1

@eneveu:你在这里。我编辑了这个到我原来的答案。但是,未经测试。 sed似乎是彻底完成的。害怕。 – Jens 2010-05-27 12:56:54

+0

@Jens:我从第二个例子中得到一个错误:“sed:-e表达式#1,字符9:未知命令:'C'” – 2010-05-28 02:23:47