2012-09-25 85 views
1

我有一個導出的CSV,有些行在記錄中間有一個換行(ASCII 012)。我需要用空格替換它,但爲每個記錄保存新行以加載它。從csv保留行中刪除換行

大部分線路都正常,但是好幾輛這樣:

輸入:

10 , ,"2007-07-30 13.26.21.598000" ,1922 ,0 , , , ,"Special Needs List Rows updated : 
Row 1 : Instruction: other :Comment: pump runs all of the water for the insd's home" ,10003 ,524 ,"cc:2023" , , ,2023 , , ,"CCR" ,"INSERT" ,"2011-12-03 01.25.39.759555" ,"2011-12-03 01.25.39.759555" 

輸出:

10 , ,"2007-07-30 13.26.21.598000" ,1922 ,0 , , , ,"Special Needs List Rows updated :Row 1 : Instruction: other :Comment: pump runs all of the water for the insd's home" ,10003 ,524 ,"cc:2023" , , ,2023 , , ,"CCR" ,"INSERT" ,"2011-12-03 01.25.39.759555" ,"2011-12-03 01.25.39.759555" 

我一直在尋找到awk中卻無法真正使感覺如何保留實際的行。

又如:

輸入:

9~~"2007-08-01 16.14.45.099000"~2215~0~~~~"Exposure closed (Unnecessary) : Garage door working 
Claim Withdrawn"~~701~"cc:6007"~~564~6007~~~"CCR"~"INSERT"~"2011-12-03 01.25.39.759555"~"2011-12-03 01.25.39.759555" 
4~~"2007-08-01 16.14.49.333000"~1923~0~~~~"Assigned to user Leanne Hamshere in group GIO Home Processing (Team 3)"~~912~"cc:6008"~~~6008~~~"CCR"~"INSERT"~"2011-12-03 01.25.39.759555"~"2011-12-03 01.25.39.759555" 

輸出:

9~~"2007-08-01 16.14.45.099000"~2215~0~~~~"Exposure closed (Unnecessary) : Garage door working Claim Withdrawn"~~701~"cc:6007"~~564~6007~~~"CCR"~"INSERT"~"2011-12-03 01.25.39.759555"~"2011-12-03 01.25.39.759555" 
4~~"2007-08-01 16.14.49.333000"~1923~0~~~~"Assigned to user Leanne Hamshere in group GIO Home Processing (Team 3)"~~912~"cc:6008"~~~6008~~~"CCR"~"INSERT"~"2011-12-03 01.25.39.759555"~"2011-12-03 01.25.39.759555" 
+2

可靠地做到這一點需要一個識別CSV格式的工具(以及用波浪號分隔的示例來判斷變體),這將允許您挑選分佈在兩行或更多行上的字段,並在重寫之前用空白替換換行符。我會提名Perl和[Text :: CSV](http://search.cpan.org/perldoc?Text%3A%3ACSV)模塊作爲使用的適當工具。 –

回答

4

方式一:的script.awk

awk -f script.awk file.txt 

內容:

BEGIN { 
    FS = "[,~]" 
} 

NF < 21 { 
    line = (line ? line OFS : line) $0 
    fields = fields + NF 
} 

fields >= 21 { 
    print line 
    line="" 
    fields=0 
} 

NF == 21 { 
    print 
} 

或者,您可以使用此一班輪:

awk -F "[,~]" 'NF < 21 { line = (line ? line OFS : line) $0; fields = fields + NF } fields >= 21 { print line; line=""; fields=0 } NF == 21 { print }' file.txt 

說明:

我對您的預期輸出做了一個觀察:看來每行應該包含完全21個字段。因此,如果您的行包含少於21個字段,請存儲行並存儲字段數。當我們循環到下一行時,該行將以一個空格連接到存儲的行,並且總計字段數。如果此字段數大於或等於21(虛線的字段總和將增加到22),請打印存儲的行。否則,如果該行包含21個字段(NF == 21),則打印它。 HTH。

2

我覺得sed是你的選擇。我假設所有記錄都以非冒號字符結尾,因此如果一行以冒號結尾,則它被識別爲異常,並應連接到前一行。

下面是代碼:

cat data | sed -e '/[^"]$/N' -e 's/\n//g' 

第一執行-e '/[^"]$/N'匹配的異常的情況下,以及在下一記錄讀取沒有空的緩衝區。然後-e 's/\n//g'刪除新的行字符。使用GNU awk

+0

謝謝,這適用於上面的行,但它們並不總是以非冒號結尾。不幸的是它可以是任何角色。 –

+0

不客氣。但在你的案例中的任何其他模式?例如虛線以單詞開始(「行」等),而通常行以行號開始(例子中爲「10」)?如果你想使用'awk',你最好總結一下足夠的模式。 –

+0

添加了上面的另一個示例 –

2

嘗試這一個班輪:

awk '{if(t){print;t=0;next;}x=$0;n=gsub(/"/,"",x);if(n%2){printf $0" ";t=1;}else print $0}' file 

想法: 算在一條線上的"數量。如果計數爲奇數,則加入下一行,否則當前行將被視爲完整行。