mtk*_*mtk 25 sed awk text-processing csv
我有一个用逗号 ( ,
)分隔的输入文件。有一些用双引号括起来的字段中包含逗号。这是示例行
123,"ABC, DEV 23",345,534.202,NAME
Run Code Online (Sandbox Code Playgroud)
我需要删除双引号和双引号内出现的所有逗号。所以上面的行应该被解析为如下所示
123,ABC DEV 23,345,534.202,NAME
Run Code Online (Sandbox Code Playgroud)
我尝试了以下使用sed
但没有给出预期的结果。
sed -e 's/\(".*\),\(".*\)/\1 \2/g'
Run Code Online (Sandbox Code Playgroud)
任何快速的运用了sed
,awk
或者任何其他Unix工具吗?
Tho*_*hor 37
如果引号是平衡的,您将需要删除每个其他引号之间的逗号,这可以表示为awk
:
awk -F'"' -v OFS='' '{ for (i=2; i<=NF; i+=2) gsub(",", "", $i) } 1' infile
Run Code Online (Sandbox Code Playgroud)
输出:
123,ABC DEV 23,345,534.202,NAME
Run Code Online (Sandbox Code Playgroud)
解释
该-F"
品牌在awk分离的双引号标志线,这意味着所有其他领域将是引号之间的文本。for 循环gsub
在所有其他字段上运行,全局替换的缩写,用空( ","
)替换逗号( ""
)。所述1
在端调用默认代码块:{ print $0 }
。
有一个很好的回应,只需一次使用 sed循环:
echo '123,"ABC, DEV 23",345,534,"some more, comma-separated, words",202,NAME'|
sed ':a;s/^\(\([^"]*,\?\|"[^",]*",\?\)*"[^",]*\),/\1 /;ta'
123,"ABC DEV 23",345,534,"some more comma-separated words",202,NAME
Run Code Online (Sandbox Code Playgroud)
解释:
:a;
是进一步分支的标签s/^\(\([^"]*,\?\|"[^",]*",\?\)*"[^",]*\),/\1 /
可以包含 3 个封闭部分
[^"]*,\?\|"[^",]*",\?
匹配一个不包含双引号的字符串,可能后跟一个逗号或一个由两个双引号括起来的字符串,没有逗号,可能后跟一个逗号。ta
将循环到:a
上一个s/
命令是否做了一些更改。循环完成后,您甚至可以添加s/ */ /g
:
echo '123,"ABC, DEV 23",345,534,"some more, comma-separated, words",202,NAME'|
sed ':a;s/^\(\([^"]*,\?\|"[^",]*",\?\)*"[^",]*\),/\1 /;ta;s/ */ /g'
Run Code Online (Sandbox Code Playgroud)
将抑制双空格:
123,"ABC DEV 23",345,534,"some more comma-separated words",202,NAME
Run Code Online (Sandbox Code Playgroud)
还可以处理平衡引号之间的多个逗号的通用解决方案需要嵌套替换。我在 perl 中实现了一个解决方案,它处理给定输入的每一行,并且只在每对其他引号中替换逗号:
perl -pe 's/ " (.+? [^\\]) " # find all non escaped
# quoting pairs
# in a non-greedy way
/ ($ret = $1) =~ (s#,##g); # remove all commas within quotes
$ret # substitute the substitution :)
/gex'
Run Code Online (Sandbox Code Playgroud)
或者简而言之
perl -pe 's/"(.+?[^\\])"/($ret = $1) =~ (s#,##g); $ret/ge'
Run Code Online (Sandbox Code Playgroud)
您可以通过管道将要处理的文本传递给命令,也可以将要处理的文本文件指定为最后一个命令行参数。