所以,你想解析一個CSV文件與awk
和修改只有一個列的子集?
首先,解析CSV字段並不像在分隔符(,
或;
)上分割那麼簡單,因爲當引用值時必須避免分割。該awk
食譜這在excellent answer by @EdMorton,並給出瞭如果使用GNU awk
,最簡潔的方法是FPAT
:(對於其他awk
S和一些特殊情況,請參閱引用答案)
awk -v FPAT='[^;]*|"[^"]+"' -v OFS=';' '...'
現在回到您的程序。 ERE參數gsub
的正確語法是/pattern/
或"pattern"
,但不是兩者都是(例如"/pattern/"
)。
這意味着你將不得不更換如下:
gsub("/\&\;/","\&",$3) --> gsub(/&/, "\\&", $3)
gsub("/\·\;/", " ",$3) --> gsub(/·/, " ", $3)
gsub("/\â\;/", "a",$3) --> gsub(/â/, "a", $3)
gsub("/\é\;/", "e",$3) --> gsub(/é/, "e", $3)
還要注意的是,在ERE正則表達式的一部分,&
和;
沒有進行轉義,但在替換字符串&
做(與\
這也需要逃脫)。
此外,要僅修改列$3
,則不需要for
循環。但是,如果您確實想要修改從$3
開始到最後$NF
結束的一系列列,則需要在每個gsub
調用中使用$i
,而不是$3
。
固定的,你awk
的程序是這樣的:
awk -v FPAT='[^;]*|"[^"]+"' -v OFS=';' '{
for (i=3; i<=NF; i++) {
gsub(/&/, "\\&", $i)
gsub(/·/, " ", $i)
gsub(/â/, "a", $i)
gsub(/é/, "e", $i)
gsub(/#/, " ", $i)
}
print
}' file.csv
(該print
末,確保每一行得到打印。)
適用於你的榜樣(並轉化爲一個班輪):
$ echo '32602;1;"Wet & Dry 5029";2663,2662' | awk -v FPAT='[^;]*|"[^"]+"' -v OFS=';' '{for (i=3;i<=NF;i++) {gsub(/&/,"\\&",$i); gsub(/·/," ",$i); gsub(/â/,"a",$i); gsub(/é/,"e",$i); gsub(/#/," ",$i)}; print}'
32602;1;"Wet & Dry 5029";2663,2662
在評論其他故障排除後,似乎是解決你的問題是不是要取代這些HTML實體因爲您的CSV文件似乎格式不正確,所以後續處理器無法解析它(可能是由於未引用;
s),所以請在完整文件中替換它們。
可以代替你像一個簡單的sed
命令指定的所有HTML實體:
sed -e 's/&/\&/g' -e 's/·/ /g' -e 's/â/a/g' -e 's/é/e/g' -e 's/#/ /g' file
後從你的'file.csv' – RomanPerekhrest
歡迎的幾個輸入線堆棧溢出,請郵寄樣本輸入和期望的輸出在代碼標籤中(按照論壇規則)。 – RavinderSingh13