我在bash中遍历一系列CSV文件,运行:
iconv --from-code=ISO-8859-1 --to-code=UTF-8 ${FILE} | \
sed -e 's/\"//g' | \
sed -e 's/, /,/g' \
> ${FILE}.utf8
运行iconv
以修复UTF-8字符,然后第一个sed
调用删除双引号字符,最后sed
调用应该删除周围的前导和尾随空格逗号。
但是,在保存的文件中我仍然有这样的一行:
FALSE,,,, 2.40,,
postgres中的COPY
命令有点笨,所以它认为“2.40”不是数值的有效语法。
我在处理CSV文件时哪里出错了?谢谢!
答案 0 :(得分:2)
可能发生的事情是,您有多个空格或多个具有空格的字段,因此您可以在具有多个空格的行上看到单个成功的空白替换结果。< / p> 顺便说一句,你可以为sed提供多个-e参数。试试这个:
... | sed -e 's/"//g' -e 's/ *, */,/g'
答案 1 :(得分:0)
您的第二个sed
仅删除尾随空格(实际上只删除一个尾随空格)。这里应该删除前导空格?
答案 2 :(得分:0)
构造其中一个以删除空格:
sed -e ':a; s/, /,/g; ta'
sed -e 's/,[ ][ ]*/,/g'
第一个将递归执行更新,直到找不到匹配的组合。 第二个将搜索空格,然后搜索一组可能的空格。
没有必要删除"
,因为默认情况下PostgreSQL在使用COPY ... WITH (FORMAT CSV)
答案 3 :(得分:0)
准备CSV以完全符合数据类型的一般替代是将所有数据导入text
(导入text
列的临时表)并让PostgreSQL类型强制机制自动完成一些工作。
特别是,当text
转换为数字类型或日期/时间类型时,会自动修剪前导和尾随空格。尝试:
SELECT ' 234 '::text::int;
SELECT ' 23.4 '::text::float8; -- incl. a leading tab
SELECT ' 2012-12-1 '::text::date; -- incl. a leading & trailing tab
所以如果你有一个像这样的表:
CREATE TABLE foo
( id integer,
col_a date,
col_b double precision
);
你可以:
CREATE TEMP TABLE foo_tmp -- dropped automatically at end of session
( id text,
col_a text,
col_b text
);
COPY foo_tmp FROM '/path/to/foo_file.csv';
INSERT INTO foo
SELECT id::int
,col_a::date
,col_b::double precision
FROM foo_tmp;
或者根据需要使用any other Postgres function准备字符串。
您只需要有效的CSV格式。