2012-04-14 15 views
0

我通過在bash CSV文件的集合迭代,運行:在一個CSV sed的更換空白(使用W/Postgres的複製命令)

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,, 

COPY命令的Postgres是一種愚蠢的,所以它認爲「2.40」不是一個數值有效的語法。

我在哪裏出錯了/我處理的CSV文件?謝謝!

回答

0

您的第二個sed只刪除尾隨空格(實際上只有一個尾隨空格)。這裏應該刪除領先空間?

+0

遺忘前導空間..它不刪除單個尾隨空間。 – Wells 2012-04-14 23:25:32

+0

你不知道;如果它有*兩個*尾部空格,則會得到一個輸出。這就是括號內的意思。 – geekosaur 2012-04-14 23:33:00

2

可能發生的情況是,您擁有多個空間或多個空間的字段,因此您可以看到一條線上有多個空白替換的成功結果。

順便說一句,你可以給sed多個-e參數。試試這個:

... | sed -e 's/"//g' -e 's/ *, */,/g' 
0

做一個構建這樣一來刪除空格:

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

第一個將遞歸執行更新,直到它找到任何匹配的組合。 第二個將搜索空間,然後搜索可能的空間組。

而且這是沒有必要刪除",因爲默認情況下的PostgreSQL瞭解他們使用COPY ... WITH (FORMAT CSV)

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