Suj*_*jit 5 python awk text-processing sed
在我们的项目中,我们需要将csv文件导入postgres.有多种类型的文件意味着文件的长度会发生变化,因为某些文件的列数较少,而某些文件的列数较少.
我们需要一种快速的方法将此文件导入postgres.我想使用postgres的COPY FROM,因为处理的速度要求非常高(每分钟几乎150个文件,每个文件大小为20K).
由于文件列号不固定,我需要在将文件传递给postgres过程之前预处理该文件.预处理只是在csv中为列添加额外的逗号,这些列在文件中不存在.
我有两个选项来预处理文件 - 使用python或使用Sed.
我的第一个问题是,预处理文件的最快方法是什么?
第二个问题是,如果我使用sed如何在说第4个,第5个逗号字段后插入逗号?
例如,如果文件有像1,23,56,we,89,2009-12-06这样的条目,我需要编辑最终输出的文件,如:1,23,56,we ,, 89 ,,,2009-12-06
您是否知道COPY FROM可以指定要导入哪些列(以及它们的顺序)?
COPY tablename ( column1, column2, ... ) FROM ...
Run Code Online (Sandbox Code Playgroud)
在 Postgres 级别直接指定要导入哪些列以及以什么顺序导入通常是最快、最有效的导入方法。
话虽如此,有一种更简单(且可移植)的方法sed(比其他帖子中介绍的方法)来替换第n次出现,例如用双逗号替换第 4 次和第 5 次出现的逗号:
echo '1,23,56,we,89,2009-12-06' | sed -e 's/,/,,/5;s/,/,,/4'
Run Code Online (Sandbox Code Playgroud)
产生:
1,23,56,we,,89,,2009-12-06
Run Code Online (Sandbox Code Playgroud)
请注意,我首先替换了最右边的字段 (#5)。
我看到您也将您的问题标记为相关,尽管您在问题正文中perl没有明确提及;perl这是一种可能的实现,它使您可以灵活地重新排序或以其他方式处理字段:
echo '1,23,56,we,89,2009-12-06' |
perl -F/,/ -nae 'print "$F[0],$F[1],$F[2],$F[3],,$F[4],,$F[5]"'
Run Code Online (Sandbox Code Playgroud)
还生产:
1,23,56,we,,89,,2009-12-06
Run Code Online (Sandbox Code Playgroud)
与 非常相似awk,郑重声明:
echo '1,23,56,we,89,2009-12-06' |
awk -F, '{print $1","$2","$3","$4",,"$5",,"$6}'
Run Code Online (Sandbox Code Playgroud)
我会把Python留给其他人。:)
关于 Perl 示例的小注释:我使用-a和-F选项进行自动分割,因此我有一个更短的命令字符串;但是,这会将换行符嵌入到最后一个字段 ( $F[5]) 中,只要该字段不必在其他地方重新排序就可以了。如果出现这种情况,则需要稍微多输入一些内容,以便通过 切换换行符chomp,然后split手动并最终打印我们自己的换行符\n(awk上面的示例没有这个问题):
perl -ne 'chomp;@F=split/,/;print "$F[0],$F[1],$F[2],$F[3],,$F[4],,$F[5]\n"'
Run Code Online (Sandbox Code Playgroud)
COMMAS_TO_DOUBLE="1 4 5"
echo '1,23,56,we,89,2009-12-06' |
sed -e `for f in $COMMAS_TO_DOUBLE ; do echo "s/,/,,/$f" ; done |
sort -t/ -k4,4nr | paste -s -d ';'`
1,,23,56,we,,89,,2009-12-06
Run Code Online (Sandbox Code Playgroud)
抱歉,没能抗拒。:)