我正在将现有数据库的模式转换为Postgresql。我想尽可能多地自动化,以避免手动错误。
原始数据库使用CLUSTERED索引,但PG(实际上)没有聚簇索引。我想写一个bash脚本来将所有出现的CLUSTERED索引替换为postgresql等价物。
基本上,我想要SUBSTITUTE这样的行:
CREATE clustered INDEX idx_foobar ON foobar (f1, f2, f3, f4,f5);
使用这样的2行替换:
CREATE INDEX idx_foobar ON foobar (f1, f2, f3, f4,f5);
CLUSTER foobar;
我认为我已经找到了匹配逻辑,我只需要正则表达式的帮助,因为我不是很熟悉。似乎有效的匹配逻辑如下:
有人可以帮助我将这个逻辑合并到一个bash脚本中,这样我就可以将它传递给要处理的文件吗?
顺便说一下,我以为我可以使用sed
来做这件事,但我不知道写一个bash脚本会更容易(也就是说更容易理解),而不是试图这样做在sed中有一个班轮 - 但我愿意接受建议。
答案 0 :(得分:1)
sed --posix "/CREATE clustered INDEX/ {
s/ *clustered */ /
s/ON *\([^( ]*\) *(.*$/& CLUSTER \1;/
}"
--posix
也适用于非GNU
我制作另一个正则表达式而不是bob Schuster(非常好的一个)只是为了有一个替代方案,允许在线上进行更多修改,如果需要用于其他目的,比如在脚本中插入注释。
这是cygwin bash上的会话(版本在线)
$ cat sample.txt
CREATE clustered INDEX idx_foobar ON foobar (f1, f2, f3, f4,f5);
blabla;
$ sed --posix "/CREATE clustered INDEX/ {s/ *clustered */ /;s/ON *\([^( ]*\) *(.*$/& CLUSTER \1;/;}" sample.txt
CREATE INDEX idx_foobar ON foobar (f1, f2, f3, f4,f5); CLUSTER foobar;
blabla;
答案 1 :(得分:0)
您可以尝试使用sed,例如:
sed -r 's/^\s*(CREATE\s*)clustered\s*(INDEX.*ON\s*)(\w*)(\s+\(.*;)$/\1\2\3\4\nCLUSTER \3;/gi' original.txt > updated.txt
我遵循了您的指导原则,这就是为什么正则表达式有点笨重,但您可以根据输入文件的实际内容修改正则表达式,以及是否要保留无关的空格。
试用正则表达式的一个好地方是:http://regex101.com
答案 2 :(得分:0)
这可能适合你(GNU sed):
sed -r 's/^(\s*CREATE) (cluster)ed(.* (\S+) \(.*\);)\s*$/\1\3\n\U\2 \L\4;/' file
答案 3 :(得分:0)
警惕Postgres中的群集不一定与您正在使用的原始数据库中的群集相同(我假设SQL Server?)。根据文档:
群集是一次性操作:随后更新表时,更改不会群集。也就是说,不会尝试根据其索引顺序存储新行或更新的行。 (如果有人愿意,可以通过再次发出命令来定期重新集群。(...))
http://www.postgresql.org/docs/current/static/sql-cluster.html
这意味着用create clustered index on table (...);
替换create index on table (...); cluster table;
并不会按照预期的方式运作。
鉴于此,坚持使用sed删除clustered
,或确保添加其他using index
部分。如果是后者,您还需要在导入的最后添加额外的cluster table
,以实际聚类数据。
您应该完全删除群集引用,并担心在导入的最后添加它们,手动或在删除脚本的一部分或之前生成其他SQL文件。