bash脚本,用于解析(和替换)文件中所有出现的文本块

时间:2013-11-03 01:48:28

标签: regex bash postgresql sed

我正在将现有数据库的模式转换为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;

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

  1. 查找以CREATE clustered INDEX开头的行(该行可能以一个或多个非换行符空格开头)
  2. 存储表格的名称(它在 ON 关键字后面的一个或多个空格后面)
  3. 从上面1中匹配的行中删除群集一词,以创建替代文字
  4. 将“\ n
  5. 将步骤1中的匹配行替换为替换文本(在步骤4中获得)
  6. 有人可以帮助我将这个逻辑合并到一个bash脚本中,这样我就可以将它传递给要处理的文件吗?

    顺便说一下,我以为我可以使用sed来做这件事,但我不知道写一个bash脚本会更容易(也就是说更容易理解),而不是试图这样做在sed中有一个班轮 - 但我愿意接受建议。

4 个答案:

答案 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文件。