pra*_*ker 4 awk text-processing csv
我有一个逗号分隔的文件,其中包含数字和字符串列。字符串列用引号引起来,引号之间可以有逗号。我如何识别列FS =","?
样本记录
"prabhat,kumar",19,2000,"bangalore,India"
Run Code Online (Sandbox Code Playgroud)
在AWK 中它应该是
$1 = "prabhat,kumar"
$2 = 19
$3 = "2000"
$4 = "bangalore,india"
Run Code Online (Sandbox Code Playgroud)
设置FS=","正在制造问题。
输入是:
"prabhat,kumar",19,2000,"bangalore,India","ABC,DEF","GHI",123,"KLM","NOP,QRS"
"prabhat,kumar",19,2000,"bangalore,India","ABC,DEF","GHI",123,"KLM","NOP,QRS"
Run Code Online (Sandbox Code Playgroud)
输出应该是:
"prabhat,kumar"|19|2000|"bangalore,India"|"ABC,DEF"|"GHI"|123|"KLM"|"NOP,QRS"
"prabhat,kumar"|19|2000|"bangalore,India"|"ABC,DEF"|"GHI"|123|"KLM"|"NOP,QRS"
Run Code Online (Sandbox Code Playgroud)
我正在尝试的代码:
awk -F"," '{for(i=1;i<=NF;i++){if(i%NF==0){ORS="\n"} {if($i ~ /^\"/ || $i ~ /\"$/) {a=a OFS $i;j++;{if(j%2==0){sub(/^\,/,X,a); print a;j=0;a=""}}} else {print $i}}} {ORS="|"}}' ORS="|" OFS=, p.txt
Run Code Online (Sandbox Code Playgroud)
首先,您应该使用合适的 CSV 解析器。例如,在 Perl 中,您可以使用Text::CSV:
安装cpanm(如果你使用 Perl,稍后你会感谢我)
$ sudo apt-get install cpanminus
Run Code Online (Sandbox Code Playgroud)
如果您不是在基于 Debian 的系统上,您应该能够使用您的发行版的包管理器安装它。
安装Text::CSV模块
$ sudo cpanm Text::CSV
Run Code Online (Sandbox Code Playgroud)解析你的文件
$ perl -MText::CSV -le '
$csv = Text::CSV->new({binary=>1});
while ($row = $csv->getline(STDIN)){
print "1:$row->[0], 2:$row->[1], 3:$row->[2], 4:$row->[3]"}' < file.csv
1:prabhat,kumar, 2:19, 3:2000, 4:bangalore,India
Run Code Online (Sandbox Code Playgroud)
正如你在上面看到的,第一个字段是$row->[0],第二个$row->[1]等等。
那是正确的方法。一个更简单但肮脏的黑客是用另一个字符替换任何带引号的逗号。然后,awk正常使用,最后,再次将它们切换回逗号。我在###这里使用,但你可以使用任何你确定永远不会出现在你的领域之一的东西。
$ sed -r 's/("[^",]+),([^",]+")/\1###\2/g' file.csv |
awk -F, '{print $1,$3}' | sed 's/###/,/g'
"prabhat,kumar" 2000
Run Code Online (Sandbox Code Playgroud)