2017-10-15 12 views
0

私は数千の行を含むcsvファイルを持っています。csvファイルの特定の列で複数の文字をAWKに置き換えるにはどうすればよいですか?

私は、このコマンドを使用してみましたが、それは

awk 'BEGIN{FS=OFS=";"} {for (i=3;i<=NF;i++) gsub("/\&amp\;/","\&",$3); gsub("/\&middot\;/", " ",$3); gsub("/\&acirc\;/", "a",$3); gsub("/\&eacute\;/", "e",$3); gsub(/\#/, " ",$3)}' file.csv 

サンプル入力動作しない特定の列

&acirc ; ---> a 
&amp ; ---> & 
&eacute ; ---> é 

でいくつかの文字交換する必要があり

:期待

32602;1;"Wet &amp; Dry 5029";2663,2662 

を出力:

32602;1;"Wet & Dry 5029";2663,2662 
+2

が – RomanPerekhrest

+1

は、スタックオーバーフローへようこそ 'file.csv'からいくつかの入力ラインを投稿し、サンプル入力と期待される出力を投稿してくださいコードタグで(フォーラムルールに従って)。 – RavinderSingh13

答えて

0

したがって、awkでCSVファイルを解析し、列のサブセットのみを変更したいですか?

まず、CSVフィールドの解析は、区切り文字(,、またはケース;)で分割するのと同じくらい簡単ではありません。これは、値を引用するときに分割しないでください。このためawkレシピはexcellent answer by @EdMortonに与えられた、とあなたはGNU awkを使用する場合、最もエレガントなアプローチがFPATであるされています

awk -v FPAT='[^;]*|"[^"]+"' -v OFS=';' '...' 

(他awk sおよびいくつかの特殊なケースでは、引用された答えを参照してください。)

あなたのプログラムに戻ります。 gsub ERE引数の正しい構文は、/pattern/または"pattern"ですが、両方ではありません(たとえば、"/pattern/")。あなたは次のように置き換える必要があります意味

gsub("/\&amp\;/","\&",$3)  --> gsub(/&amp;/, "\\&", $3) 
gsub("/\&middot\;/", " ",$3) --> gsub(/&middot;/, " ", $3) 
gsub("/\&acirc\;/", "a",$3) --> gsub(/&acirc;/, "a", $3) 
gsub("/\&eacute\;/", "e",$3) --> gsub(/&eacute;/, "e", $3) 

はまた、(ERE正規表現の一部では、&;をエスケープする必要はありませんのでご注意ますが、置換文字列&でありません\もエスケープする必要があります)。

また、$3という列だけを変更する場合は、forループは必要ありません。しかし、実際に$3で始まり、最後に$NFで終わる列の範囲を変更する場合は、$3の代わりにそれぞれgsubコールで$iを使用する必要があります。固定

は、あなたのawkプログラムは次のようになります。

awk -v FPAT='[^;]*|"[^"]+"' -v OFS=';' '{ 
    for (i=3; i<=NF; i++) { 
     gsub(/&amp;/, "\\&", $i) 
     gsub(/&middot;/, " ", $i) 
     gsub(/&acirc;/, "a", $i) 
     gsub(/&eacute;/, "e", $i) 
     gsub(/#/, " ", $i) 
    } 
    print 
}' file.csv 

(末尾のprintは、各ラインが印刷されますが保証されます。)あなたの例に適用

(ワンライナーに変換):コメント欄に追加のトラブルシューティング後

$ echo '32602;1;"Wet &amp; Dry 5029";2663,2662' | awk -v FPAT='[^;]*|"[^"]+"' -v OFS=';' '{for (i=3;i<=NF;i++) {gsub(/&amp;/,"\\&",$i); gsub(/&middot;/," ",$i); gsub(/&acirc;/,"a",$i); gsub(/&eacute;/,"e",$i); gsub(/#/," ",$i)}; print}' 
32602;1;"Wet & Dry 5029";2663,2662 

、あなたの問題を解決するには、中にこれらのHTMLエンティティを置き換えることではなかったように思えますあなたのCSVファイルが不正な形になっていると思われるので、後続のプロセッサがそれを解析できないようにします(恐らく引用符なしの;のためです)。

あなたが好きなあなたは、簡単なsedコマンドで指定されたすべてのHTMLエンティティを置き換えることができます。

sed -e 's/&amp;/\&/g' -e 's/&middot;/ /g' -e 's/&acirc;/a/g' -e 's/&eacute;/e/g' -e 's/#/ /g' file 
+0

ありがとうございますが、まだ動作しません。 は、ここに私のcsvファイルのサンプルラインである---> 32602; 1;「ウェット&ドライ5029」;私はまだそれが&で置き換えられていない&を持って 私はcsvファイルに適用される2663,2662。 理由は何ですか? –

+0

今見てみると、問題は ';'で分割されていたので、本当に適切なCSV解析が必要です。 – randomir

+0

本当に明確な情報をありがとう。しかし、実際にはまだ問題があります。 csvはうまくコード化されていないので、私は特殊文字を含むこれらの文字を置き換えたいのです ";" "#"をawkで使用すると、csvをデータベースにインポートするときに問題が発生します。新しいコードを適用すると、今度は列3の多くの行に ";"スペースの代わりに。 –

関連する問題