したがって、awk
でCSVファイルを解析し、列のサブセットのみを変更したいですか?
まず、CSVフィールドの解析は、区切り文字(,
、またはケース;
)で分割するのと同じくらい簡単ではありません。これは、値を引用するときに分割しないでください。このためawk
レシピはexcellent answer by @EdMortonに与えられた、とあなたはGNU awk
を使用する場合、最もエレガントなアプローチがFPAT
であるされています
awk -v FPAT='[^;]*|"[^"]+"' -v OFS=';' '...'
(他awk
sおよびいくつかの特殊なケースでは、引用された答えを参照してください。)
あなたのプログラムに戻ります。 gsub
ERE引数の正しい構文は、/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
で終わる列の範囲を変更する場合は、$3
の代わりにそれぞれgsub
コールで$i
を使用する必要があります。固定
は、あなたの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ファイルが不正な形になっていると思われるので、後続のプロセッサがそれを解析できないようにします(恐らく引用符なしの;
のためです)。
あなたが好きなあなたは、簡単なsed
コマンドで指定されたすべてのHTMLエンティティを置き換えることができます。
sed -e 's/&/\&/g' -e 's/·/ /g' -e 's/â/a/g' -e 's/é/e/g' -e 's/#/ /g' file
が – RomanPerekhrest
は、スタックオーバーフローへようこそ 'file.csv'からいくつかの入力ラインを投稿し、サンプル入力と期待される出力を投稿してくださいコードタグで(フォーラムルールに従って)。 – RavinderSingh13