从表名作为第一列、字段作为第二列的文件创建 SQL 脚本

从表名作为第一列、字段作为第二列的文件创建 SQL 脚本

我有一个文本文件,其中包含以空格分隔的两列:

Foo Param1
Foo Param2
Foo Param3
Foo Param4
Foo Param5
Bar Stuff1
Bar Stuff2
Bar Param3
Bar Stuff4
etc

第一列是组名称,第二列是该组内的唯一属性(属性名称可能出现在两个不同的组中,但这很正常)。

我希望可以从这个文件创建一个如下的 SQL 文件:

CREATE TABLE "Foo" (
   id SERIAL PRIMARY KEY,
   Param1 text,
   Param2 text,
   Param3 text,
   Param4 text,
   Param5 text
);
CREATE TABLE "Bar" (
   id SERIAL PRIMARY KEY,
   Stuff1 text,
   Stuff2 text,
   Param3 text,
   Stuff4 text
);

表名来自文件的第一列,第二列用作要创建的字段。

到目前为止我所尝试的基于线程,是这样的:

awk -F ' ' 'BEGIN{IFS=","}NR>1{arr[$1]++}END{for (a in arr) print "CREATE TABLE IF NOT EXISTS " a " (" ${arr[*]} " )"}' file.txt

但这显然不起作用。

有没有一种简单的方法可以在 bash / Ubuntu 22.04 中实现这一目标?


对于背景:我已经使用提取图像元数据exiftool我想喂一个PostgreSQL每个数据库有一个表团体级别 0,所有标签均作为属性找到。

因此,文本文件中的第一列对应于组名称,例如EXIFXMPICC_Profile,并且例如对于EXIF组,第二列具有诸如Artist、等值ColorSpaceFNumber

答案1

不要做。这是一个非常糟糕的设计模式。如果您的源数据文件有一对新的“组值”或丢失它 - 您是否要为该组重建一个表?你们有多少个小组?你确定这是一个小常数吗?您打算如何参数化表名称?

只需创建一个遵循您已有数据的表:

create table data (
   group text,
   flag text,
   comment text,
   primary key(group, flag)
);

了解 EAV 数据库模式:https://en.wikipedia.org/wiki/Entity%E2%80%93attribute%E2%80%93value_model

答案2

干得好。格式并不完全是你想要的,但我相信 PostgreSQL 应该对此很满意

awk '
    # continuation lines separated by comma
    $1 == table { print "," }

    # new table needs preamble
    $1 != table {
        # may need to finish previous definition
        if(table > "") { print ");" }

        # preamble
        table=$1;
        printf "create table \"%s\" (\n", table
        print "id SERIAL PRIMARY KEY,"
    }

    # field
    { printf "%s text\n", $2 }

    # close final table
    END { print ");" }
' datafile

答案3

使用任何 awk:

$ cat tst.awk
$1 != prev {
    printf "%sCREATE TABLE \"%s\" (\n   id SERIAL PRIMARY KEY", end, $1
    end = "\n);\n"
    prev = $1
}
{ printf ",\n   %s text", $2 }
END { printf "%s", end }

$ awk -f tst.awk file
CREATE TABLE "Foo" (
   id SERIAL PRIMARY KEY,
   Param1 text,
   Param2 text,
   Param3 text,
   Param4 text,
   Param5 text
);
CREATE TABLE "Bar" (
   id SERIAL PRIMARY KEY,
   Stuff1 text,
   Stuff2 text,
   Param3 text,
   Stuff4 text
);

相关内容