如何在csv文件的特定列中用AWK替换多个字符?
我有一个csv文件,其中包含数千行 我需要替换特定列中的一些字符如何在csv文件的特定列中用AWK替换多个字符?,csv,awk,Csv,Awk,我有一个csv文件,其中包含数千行 我需要替换特定列中的一些字符 â ; ---> a & ; ---> & é ; ---> é 我试过使用这个命令,但不起作用 awk 'BEGIN{FS=OFS=";"} {for (i=3;i<=NF;i++) gsub("/\&\;/","\&",$3); gsub("/\·\;/", " ",$3); gsub("/\&
â ; ---> a
& ; ---> &
é ; ---> é
我试过使用这个命令,但不起作用
awk 'BEGIN{FS=OFS=";"} {for (i=3;i<=NF;i++) gsub("/\&\;/","\&",$3); gsub("/\·\;/", " ",$3); gsub("/\â\;/", "a",$3); gsub("/\é\;/", "e",$3); gsub(/\#/, " ",$3)}' file.csv
预期产出:
32602;1;"Wet & Dry 5029";2663,2662
那么,您想用
awk
解析CSV文件并只修改列的子集吗
首先,解析CSV字段不像在分隔符(,
,或者在您的情况下是;
)上拆分那样简单,因为在引用值时必须避免拆分。这方面的awk
方法在中给出,如果您使用GNUawk
,最优雅的方法是:
(对于其他awk
s和一些特殊情况,请参见引用的答案。)
现在回到你的节目。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 regexp部分中,和和代码>不必转义,但在替换字符串中,&
需要转义(使用同样需要转义的\
)
此外,要仅修改列$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
在注释中进行额外的故障排除之后,问题的解决方案似乎不是替换某些特定列中的HTML实体,而是替换整个文件中的HTML实体,因为您的CSV文件似乎格式不正确,因此后续处理器无法解析它(可能是由于未加引号的;
s)
您可以使用简单的sed
命令替换指定的所有HTML实体,如:
sed -e 's/&/\&/g' -e 's/·/ /g' -e 's/â/a/g' -e 's/é/e/g' -e 's/#/ /g' file
从您的文件.csv中发布几行输入行欢迎来到stack overflow,请在代码标签中发布示例输入和预期输出(根据论坛规则)。谢谢您的回答,但还不起作用。这是我的csv文件的一个示例行-->32602;1.“干湿5029”;26632662当我申请csv文件时,我仍然拥有&;它在&中没有被替换。知道为什么吗?现在看看,问题是在上拆分代码>,因此您确实需要正确的CSV解析。感谢您提供非常清晰的信息。但实际上,我仍然有一个问题。csv编码不好,这就是为什么我想用awk替换这些包含特殊字符“;”和“#”的字符,因为这会在我将csv导入数据库时引发问题。当我应用新代码时,我现在在第3列a“;”中有很多行,而不是空格。在这种情况下,我建议您尝试使用一个简单的sed-e/&/\&/g'-e's/·;//g'-e's/â/a/g'-e's/é/e/g'-e's/#//g'file>newfile
而不是使用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
$ 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
sed -e 's/&/\&/g' -e 's/·/ /g' -e 's/â/a/g' -e 's/é/e/g' -e 's/#/ /g' file