用CSV中的sed替换空格(使用w / postgres copy命令)

时间:2012-04-14 23:20:46

标签: linux postgresql sed

我在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文件时哪里出错了?谢谢!

4 个答案:

答案 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格式。