您的FPAT
要求每個字段至少包含一個字符,但您希望識別空字段爲零字符。在FPAT
末
gawk 'BEGIN { FPAT = "([^,]+)|(\"[^\"]+\")|" }
{ printf "%d:%d:", NR, NF; for (i = 1; i <= NF; i++) printf("[%s]", $i); print "" }'
注意額外|
:另一種添加到FPAT
允許零個字符。該操作只是標識記錄號,字段數,並用方括號括住每個字段的值。
當你的數據串提供給該腳本,輸出:
1:8:["RAM"]["31st street, Bengaluru, India"][][][]["7865431234"][]["VALID"]
,顯示了4個空場很清楚。
現在你要做的就是處理:
"Mr ""Manipulator"", the Artisan","29th Street, Delhi, India",,,"",,,"INVALID"
那裏有引號裏面的值雙引號。這並不可怕難以管理:
gawk 'BEGIN { FPAT = "([^,]+)|(\"([^\"]|\"\")*\")[^,]*|" }
{ printf "%d:%d:", NR, NF; for (i = 1; i <= NF; i++) printf("%d[%s]", i, $i); print "" }' "[email protected]"
的FPAT
說,一個領域是:
注意「可選的非逗號數據」應該是空的,只出現在格式不正確的CSV數據中。
給定的輸入數據:
"RAM","31st street, Bengaluru, India",,,,"7865431234",,"VALID"
"Mr ""Manipulator"", the Artisan","29th Street, Delhi, India",,,,,,"INVALID"
"Some","","Empty","",Fields "" Wrapped,"",in quotes
"Malformed" CSV,Data,"Note it has data after" a close quote,"and before a comma,",,"INVALID"
這產生:
1:8:1["RAM"]2["31st street, Bengaluru, India"]3[]4[]5[]6["7865431234"]7[]8["VALID"]
2:8:1["Mr ""Manipulator"", the Artisan"]2["29th Street, Delhi, India"]3[]4[]5[]6[]7[]8["INVALID"]
3:7:1["Some"]2[""]3["Empty"]4[""]5[Fields "" Wrapped]6[""]7[in quotes]
4:6:1["Malformed" CSV]2[Data]3["Note it has data after" a close quote]4["and before a comma,"]5[]6["INVALID"]
注意,場數被包括作爲一個前綴添加到括號數據(所以我調整了打印格式略)。
關於唯一不能處理的格式是可以在字段的數據中嵌入換行符 - 根據基於行的輸入的性質,它假定沒有字段被拆分爲多行。 (這也意味着它不會正確識別以雙引號開頭的字段,並且在行尾之前沒有匹配的雙引號。我想你可以添加一個替代方法來識別該字段。使數據的權利。)
注意建議在Sobrique的answer用設計來處理CSV用於處理CSV的工具。這通常是一個好主意,而且你必須處理的變體組合越複雜,它的想法就越好。這與您應該考慮使用的正則表達式非常接近。還要注意,儘管RFC 4180正式和嚴格地定義了一個CSV版本,但有多個程序(包括MS Office)可以處理不同但相關的格式。
這些值本身是否可以包含逗號? – neuhaus
是的,因爲第二個字段是地址。它可以包含任意數量的逗號。 –
我會使用perl和[Text :: CSV]模塊(http://search.cpan.org/~makamaka/Text-CSV-1.33/lib/Text/CSV.pm)。 – neuhaus