我有一个文本文件,其中包含以空格分隔的两列:
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,所有标签均作为属性找到。
因此,文本文件中的第一列对应于组名称,例如EXIF
、XMP
或ICC_Profile
,并且例如对于EXIF
组,第二列具有诸如Artist
、等值ColorSpace
。FNumber
答案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
);