awk中的CSV格式替换引号

时间:2017-09-27 16:38:06

标签: bash csv awk

我正在使用awk脚本解析bash中的csv。使用"

引用的值

"1";"2";"3"

有时我没有在像

这样的值中转义引号

"1";"2"2";"3"我需要翻译为"1";"22";"3"

如何删除这些"里面2美元?首先我尝试检查2美元,如果里面有引号,但我卡住了。如果我使用gsub,它将删除$ 2中的所有引号,我将获得"1";22;"3"。我想过在gensub中使用gsub,但是没有找到如何将函数传递给gensub的第二个参数。

cat test | awk 'BEGIN {OFS=FS=";"} \ {if ($2 ~ /^\".*.[\"].*\"$/) {$2 = "need help here")} \ print}'

**************** UPDATE ****************

也许有另一种解决方法。 awk是否有任何特殊选项,不仅可以设置分隔符,还可以为分隔值设置引号?如果1美元等等可以被视为"价值"那将是非常棒的。但作为价值本身在引号

6 个答案:

答案 0 :(得分:1)

快速而肮脏:使用gsub并放回外部引号:

 $ echo '"1";"2"2";"3"' | awk -v q='"' 'BEGIN {FS=OFS=";"} {gsub(q,"",$2); $2 = q $2 q; print}'
"1";"22";"3"

答案 1 :(得分:1)

echo '"1";"2"2";"3"'| awk '{sub(/2"2/,"22")}1'

"1";"22";"3"

答案 2 :(得分:0)

以下摘录是一个潜在的答案。 awk语句使用RS代替FS,因此"1""2"2"等每个部分都会单独打印。然后tr命令删除所有引号。接下来,sed命令将引号添加回整个字段。最后,paste命令添加分号。

echo '"1";"2"2";"3"' | awk 'BEGIN{RS=";"}{print $1}' | tr -d '"' | sed -r 's|(.*)|"\1"|' | paste -sd ";"

答案 3 :(得分:0)

从所有字段中删除散布的内容:

awk 'BEGIN{FS=OFS="\";\""}
     { for (i=1;i<=NF;i++) 
          gsub(/"/,"",$i); 
       printf "\"%s\"\n", $0 
     }' input.txt

所以输入:

$ cat input.txt
"1";"2"2";"3"
"1";"1"234"567""8";"1"2"3"4"5"""

你会得到:

$ awk 'BEGIN{FS=OFS="\";\""}{for (i=1;i<=NF;i++) gsub(/"/,"",$i); printf "\"%s\"\n", $0 }' input.txt
"1";"22";"3"
"1";"12345678";"12345"

真的只想要$ 2?

 awk 'BEGIN{FS=OFS="\";\""}{gsub(/"/,"",$2); printf "\"%s\"\n", $0}' input.txt
 ""1";"22";"3""
 ""1";"12345678";"1"2"3"4"5""""

答案 4 :(得分:0)

这应该正确处理正确的转义引号以及格式错误的单引号。我假设每个字段都应该引用

echo '"1";"2"2";"3""4"' | awk -F';' -v OFS=';' '{
    for (i=1; i<=NF; i++) {
        sub(/^"/,"",$i)
        sub(/"$/,"",$i)
        gsub(/""/,SUBSEP,$i)
        gsub(/"/,"",$i)
        gsub(SUBSEP,"\"\"",$i)
        $i = "\"" $i "\""
    }
    print
}'
"1";"22";"3""4"

注意,将打破"1";"2;3"数据

答案 5 :(得分:0)

如果您的输入在字段中包含;,那么您的输入是不明确的,因为无法判断"foo";"bar"是2个单独的字段还是单个字段,因此它不能解析。

如果您的输入在字段中不能包含;,那么字段周围的封闭引号不是必需的,您只需要:

$ awk 'BEGIN{FS="\";\""; OFS=";"} {gsub(/"/,""); $1=$1} 1' file
1;22;3

或者如果你觉得引用很漂亮:

$ awk 'BEGIN{FS=";"; OFS="\";\""} {gsub(/"/,""); $1="\""$1; $NF=$NF"\""} 1' file
"1";"22";"3"