0

我正在将现有数据库的模式转换为 Postgresql。我想尽可能多地自动化,以避免手动错误。

原始数据库使用 CLUSTERED 索引,但是 PG 并没有(真的)有聚集索引。我想编写一个 bash 脚本来将所有出现的 CLUSTERED 索引替换为 postgresql 等价物。

本质上,我想像这样替换行:

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;

我想我已经制定了匹配逻辑,我只需要正则表达式的帮助,因为我不是很熟悉。似乎有效的匹配逻辑如下:

  1. 查找以 CREATE clustered INDEX 开头的行(该行可能以一个或多个非换行符开头)
  2. 存储表的名称(它在ON关键字后跟一个或多个空格)
  3. 从上面 1 中匹配的行中删除聚集的单词以创建替换文本
  4. 将“\nCLUSTER $tablename”附加到上述步骤 3 中的替换文本
  5. 用替换文本替换第 1 步中的匹配行(在第 4 步中获得)

有人可以帮助我将此逻辑合并到 bash 脚本中,以便我可以将它传递给要处理的文件吗?

顺便说一句,我认为我可以使用它sed来执行此操作,但我不知道编写 bash 脚本是否会更容易(即更容易理解),而不是尝试在 sed 中作为单行来执行此操作 - 但我我愿意接受建议。

4

4 回答 4

1
sed --posix "/CREATE clustered INDEX/ {
   s/ *clustered */ /
   s/ON *\([^( ]*\) *(.*$/& CLUSTER \1;/
   }"

--posix为了可用于非 GNU,我还制作了另一个正则表达式,而不是 bob Schuster(非常好的一个),只是为了有一个替代方法,如果需要其他目的(例如在脚本中插入注释),可以在行上进行更多修改。

这是关于 cygwin bash 的会话(版本 oneline)

$ 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;
于 2013-11-03T08:06:59.243 回答
0

这可能对您有用(GNU sed):

sed -r 's/^(\s*CREATE) (cluster)ed(.* (\S+) \(.*\);)\s*$/\1\3\n\U\2 \L\4;/' file
于 2013-11-03T11:10:14.140 回答
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

于 2013-11-03T04:06:42.080 回答
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;不会按您期望的方式工作。

鉴于此,坚持clustered使用 sed 删除,或确保添加附加using index部分。如果是后者,您还需要cluster table在导入的最后添加一个额外的内容,以实际对数据进行聚类。

我认为您应该完全删除集群引用,并担心在导入的最后添加它们,无论是手动还是通过生成一个附加的 SQL 文件作为删除脚本的一部分或在删除脚本之前。

于 2013-11-03T13:13:30.900 回答