SQLITE3通过Mac终端导入.csv并跳过第一行

时间:2017-08-18 04:00:33

标签: bash macos terminal sqlite

我有数千个.csv个文件要导入sqlite3数据库。每个.csv文件的第一行都有标签。

我的想法是对文件名运行for循环并使用.import命令导入它们:

    sqlite3 options.db ".mode csv data" ".import $f data"

问题是这将导入包含标签的第一行。

问题:如何在不导入每个文件的第一行的情况下.import .csv个文件?

感谢您的帮助! :d

3 个答案:

答案 0 :(得分:1)

您可以为sqlite安装Spatialite扩展并从每个csv创建一个虚拟表 - 它将自动使用第一行作为列名称 - 然后只需创建一个新表,或者通过选择所有表来导入到现有表中您创建的虚拟表中的记录。显然,您需要创建一个执行此操作的脚本,因为您要导入数千个csv文件。

或者,您可以编写一个使用Unix cat函数的脚本,但如果要将所有文件导入同一个表,则会跳过第一行。

或编写一个解析第一行的脚本来定义表create命令中的列,然后遍历其余行以填充新表。

这些选项是否满足您的需求?

答案 1 :(得分:1)

您可以使用GNU awk(我无法访问Mac awk,因此无法测试)跳过第一行并添加缺少的列:

$ cat test
1,1
2,2
$ awk '
BEGIN { FS=OFS="," }        # set separators
FNR==1 { next }             # skip the first record(s)
NF==2 { NF=4 }              # if field count is 2 set it to 4
1                           # output
' test # > newpath/newfile  # you can use * and then some
2,2,,

如果我从评论中正确理解到另一个答案,请替换NF值以满足您的需求(NF==18 { NF=23 })。如果NF=4部分在Mac awk中不起作用,您可以将其替换为print $0 OFS OFS OFS OFS OFS; next。 现代GNU awks具有就地编辑的可能性。例如,请参阅this

答案 2 :(得分:1)

假设file1.csv看起来像这样:

File1,Line1
File1,Line2
File1,Line3
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18
1,2,3,4,5,6

file2.csv看起来像这样:

File2,Line1
File2,Line2
File2,Line3
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18
1,2,3,4,5,6

然后,您可以awk打印所有CSV文件,同时跳过第一行(其中FNR,即文件行号为1),如下所示:

awk -F, 'FNR==1{next} 1' *csv

<强>输出

File1,Line2
File1,Line3
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18
1,2,3,4,5,6
File2,Line2
File2,Line3
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18
1,2,3,4,5,6

然后你可以检查每一行上的字段数,如果它不是23,可以根据需要添加任意数量的逗号23:

awk -F, 'FNR==1{next} NF!=23{$0=$0 substr(",,,,,,,,,,,,,,,,,,,,,,",1,23-NF)}1' *csv

<强>输出

File1,Line2,,,,,,,,,,,,,,,,,,,,,
File1,Line3,,,,,,,,,,,,,,,,,,,,,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,,,,,
1,2,3,4,5,6,,,,,,,,,,,,,,,,,
File2,Line2,,,,,,,,,,,,,,,,,,,,,
File2,Line3,,,,,,,,,,,,,,,,,,,,,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,,,,,
1,2,3,4,5,6,,,,,,,,,,,,,,,,,

因此,作为一个实际的完整解决方案,您可以这样做:

awk -F, 'FNR==1{next} NF!=23{$0=$0 substr(",,,,,,,,,,,,,,,,,,,,,,",1,23-NF)}1' *csv > NewBigFile.csv

然后将NewBigFile.csv导入sqlite

相关问题