0

我在 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

4 回答 4

2

可能正在发生的事情是您有多个空格或多个字段具有空格,因此您会在包含多个空格的行上看到单个成功的尾随空白替换的结果。

顺便说一句,您可以为 sed 提供多个 -e 参数。尝试这个:

... | sed -e 's/"//g' -e 's/ *, */,/g'
于 2012-04-14T23:29:25.163 回答
0

您的第二个sed仅删除尾随空格(实际上,只有一个尾随空格)。这里应该删除前导空格?

于 2012-04-14T23:23:23.687 回答
0

准备 CSV 以完全适合数据类型的一般替代方法text是将所有数据导入(到带有text列的临时表中)并让 PostgreSQL 类型强制机制自动完成一些工作。

text特别是,当 a转换为数字类型或日期/时间类型时,会自动修剪前导和尾随空格。尝试:

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;

或者根据需要使用任何其他 Postgres 函数来准备字符串。

您只需要一个有效的 CSV 格式。

于 2012-04-17T11:23:51.483 回答
0

做一个这样的构造来删除空格:

sed -e ':a; s/, /,/g; ta'
sed -e 's/,[ ][ ]*/,/g'

第一个将递归执行更新,直到找不到匹配的组合。第二个将搜索空间,然后是一组可能的空间。

并且没有必要删除",因为默认情况下 PostgreSQL 在使用时会理解它们COPY ... WITH (FORMAT CSV)

于 2012-04-15T05:34:13.333 回答