在Unix文件中全局查找2个字符串之间的文本

时间:2013-03-25 15:15:08

标签: unix design-patterns sed full-text-search

我有多个包含DDL和DML的.sql文件。

1)在一组文件中有一个DDL(创建表...),然后是DML(Merge into ....),然后是DDL(drop table ...),如下所示:

    CREATE TABLE T1 (col1 ...);
    Merge into T2 using T1.....;
    Drop table T1;

2)在第二组中,上述模式有多个重复:

    CREATE TABLE T1 (col1 ...);
    Merge into T2 using T1.....;
    CREATE TABLE T3 (col1 ...);
    Merge into T4 using T1 and T3.....;
    Drop table T1;
    Drop table T3;

我需要从每个源文件创建2个文件:一个包含所有DDL,另一个包含所有DML。我已经尝试过sed首先在CREATE和分号之间搜索并指向DDL文件,然后在Merge和分号之间搜索并指向DML文件,最后在Drop和分号之间搜索并附加到上面的DDL文件。

    sed -n '/CREATE/,/;/p' $SRCFILE > $TGTDDLFILE
    sed -n '/Merge/,/;/p' $SRCFILE > $TGTDMLFILE
    sed -n '/Drop/,/;/p' $SRCFILE >> $TGTDDLFILE

它适用于Set 1但不适用于第2组。有没有办法可以缩放它以应用于每个出现,以便它也涵盖Set 2。 如果没有,还有其他办法吗?

感谢您的帮助。感谢

2 个答案:

答案 0 :(得分:0)

您可以使用类似

的内容
    sed -n '/CREATE/p' $SRCFILE > $TGTDDLFILE
    sed -n '/Merge/p' $SRCFILE > $TGTDMLFILE
    sed -n '/Drop/p' $SRCFILE >> $TGTDDLFILE

如果您引用的文件在一行中有一个SQL语句,这将执行您要查找的内容。如果一行上有多个SQL语句而多行上有一个SQL语句,它将失败。

如果是这种情况,您也可以使用grep

    cat $SRCFILE | grep 'CREATE' > $TGTDDLFILE
    cat $SRCFILE | grep 'Merge' > $TGTDMLFILE
    cat $SRCFILE | grep 'Drop' >> $TGTDDLFILE

答案 1 :(得分:0)

原始sed脚本中的一个问题是,您告诉sed查找以(例如)CREATE开头并以';'结尾的一系列行 - 当你要求它匹配时,sed不会将单行视为一个范围,因此它看不到';'当它与CREATE在同一行时。

试试这个版本,看看效果更好:

sed -ne 'H;/CREATE/h;/;/{s/.*//;x;/^CREATE/p;}' $SRCFILE > $TGTDDLFILE

第一个命令(H)将当前行放入保留空间,无论我们是否需要它(这将处理CREATE和';'之间的行)。如果该行包含CREATE,我们用它覆盖保留空间,以便那里的行以CREATE开头。现在,如果该行包含';'我们擦除当前行并将其与保留空间交换。如果保留空间内容以CREATE开头,我们将其打印出来。这里可以清除冗余,但代价是在脚本中添加更多内容,所以我没有打扰。除非你有庞大的文件,否则无关紧要。