使用bash在Ubuntu中将大.csv文件转换为.prn(大约3.5 GB)

时间:2016-09-30 06:17:09

标签: excel bash csv ubuntu awk

我有一个非常大的.csv文件,大小约为3.5 GB,因为我正在处理大数据,我需要将此文件转换为.prn文件,该文件用空格分隔符分隔列。

以下是文件中的示例输入值 -

  

UNT ,Gujarat,84716050,25669.69,UNITS," QX-870,IND BARCODE SCANNER,SW RSTR,LD,SRL + ETHNT S / N.:3402030。   FIS-0870-1004G",INAMD4,男,2015年5月1日,艾哈默德巴德,进口,马来西亚,1274

     

UNT ,Gujarat,84716050,25669.69,UNITS," QX-870,IND BARCODE SCANNER,SW RSTR,LD,SRL + ETHNT S / N.:3405176。   FIS-0870-1004G",INAMD4,男,2015年5月1日,艾哈默德巴德,进口,马来西亚,1275

     

UNT ,Gujarat,84716050,25669.69,UNITS," QX-870,IND BARCODE SCANNER,SW RSTR,LD,SRL + ETHNT S / N.:3405181。   FIS-0870-1004G",INAMD4,男,2015年5月1日,艾哈默德巴德,进口,马来西亚,1276

     

KGS ,古吉拉特邦,29213090,187897.88,KILOGRAMS,MEMANTINE HYDROCHLORIDE。批号。 134614003,INAMD4,W,2015年5月1日,艾哈默德巴德,进口,意大利,5277

现在,如果仔细观察,每个分区都是文件的一行,您还可以观察到每个单元格都用逗号分隔。但我们也可以在第1行 - " QX-870,IND BARCODE SCANNER,SW RSTR,LD,SRL + ETHNT S / N.:3402030中观察到。 FIS-0870-1004G&#34。包含几个逗号。所以,如果我使用逗号(,)作为分隔符,那么我将最终分开" QX-870"和" IND BARCODE SCANNER"和" SW RSTR"和" LD"和" SRL + ETHNT S / N.:3402030。 FIS-0870-1004G&#34。 ,我不想要。所以,我浏览互联网,发现我们可以使用Microsoft Excel通过以不同的格式保存文件(我选择.prn格式解决了我的问题)来改变文件的格式但这个伟大的工具无法转换更大文件(3.5 GB)所以,我希望我的输出像这样,即行号。第1行第1行,第行2 pn第2行。

  

UNT 古吉拉特邦84716050 25669.69 UNITS" QX-870,IND   BARCODE SCANNER,SW RSTR,LD,SRL + ETHNT S / N.:3402030。 FIS-0870-1004G"。
  INAMD4 M 2015-05-01艾哈迈达巴德进口马来西亚1
  274

     

UNT 古吉拉特邦84716050 25669.69 UNITS" QX-870,IND   BARCODE SCANNER,SW RSTR,LD,SRL + ETHNT S / N.:3405176。 FIS-0870-1004G"。
  INAMD4 M 2015-05-01艾哈迈达巴德进口马来西亚1
  275

     

UNT 古吉拉特邦84716050 25669.69 UNITS" QX-870,IND   BARCODE SCANNER,SW RSTR,LD,SRL + ETHNT S / N.:3405181。 FIS-0870-1004G"。
  INAMD4 M 2015-05-01艾哈迈达巴德进口马来西亚1
  276

     

KGS 古吉拉特邦29213090 187897.88 KILOGRAMS MEMANTINE   盐酸盐。批号。 134614003 INAMD4 W 2015-05-01
  艾哈迈达巴德进口意大利5 277

3 个答案:

答案 0 :(得分:1)

我发现在awk中很难做到这一点。所以,我在Perl中做到了。如果它符合您的需要,请随意使用。

1. A Column is protected with double quotes when it embeds a comma + Column could be "A Cube, Office" 2. A Column could have embedded double quotes. + Column could be "A ""Cube"" Office" + Column could be """Cube"" Office" + Column could be "Cube ""Office""" + Column could be """Cube Office"""

尝试以下perl代码。它将线条转换为管道分隔的字段。如果您满意,可以将其转换为制表符分隔的字段,并可能将列切割为固定宽度以进行打印。

#!/usr/bin/perl -w
use strict;

# read next line
while (my $line=<>) {    
   # remove new line character from the end of line
   chomp($line);
   # protect double-quotes using alarm-bell-quotes
   $line=~s/["]["]([^"]*)["]["]/\a$1\a/g;

   # $out holds the processed columns
   my $out="";    
   while (1) {    
      my $matched=0;
      # Extract a double-quoted column    
      if ($line=~s/^["](.*?)["][,]//) { $out="$out$1|"; $matched=1; }
      # Extract a non-double-quoted column
      if ($line=~s/^([^",]*?)[,]//) { $out="$out$1|"; $matched=1; }    
      # If no more columns, break loop
      last if (!$matched);
   }

   # Put back the double-quotes (by replacing alarm-bells)
   $out=~s/\a/"/g;
   print "$out\n";    
}

示例运行:

$ cat data1
2,"1.7 Cubic Foot Compact ""Cube"" Office Refrigrators",Barry French,293,457.81,208.16,68.02,Nunavut,Appliances,0.58,
3,"1.7 Cubic, Foot Compact, Cube, Office Refrigrators",Barry French,293,457.81,208.16,68.02,Nunavut,Appliances,0.58,
3,"1.7 Cubic, Foot Compact, ""Cube"", Office Refrigrators",Barry French,293,457.81,208.16,68.02,Nunavut,Appliances,0.58,


$ cat data1 | ./3.pl
2|1.7 Cubic Foot Compact "Cube" Office Refrigrators|Barry French|293|457.81|208.16|68.02|Nunavut|Appliances|0.58|
3|1.7 Cubic, Foot Compact, Cube, Office Refrigrators|Barry French|293|457.81|208.16|68.02|Nunavut|Appliances|0.58|
3|1.7 Cubic, Foot Compact, "Cube", Office Refrigrators|Barry French|293|457.81|208.16|68.02|Nunavut|Appliances|0.58|

答案 1 :(得分:1)

从您的问题中不清楚,因为您没有提供我们可以测试的样本输入/输出,但是您想要做的就是这样的声音:

$ cat tst.awk
BEGIN {
    split("7 10 15 12 4",w)
    FPAT="[^,]*|\"[^\"]*\""
}
{
    gsub(/""/,RS)
    for (i=1;i<=NF;i++) {
        gsub(/"/,"",$i)
        gsub(RS,"\"",$i)
        printf "<%-*s>", w[i], substr($i,1,w[i])
    }
    print ""
}

$ cat file
abcde,"ab,c,de","ab ""c"" de","a,""b"",c",ab
abcdefghi,"xyab,c,de","xyzab ""c"" de",abc,abcdefg

$ awk -f tst.awk file
<abcde  ><ab,c,de   ><ab "c" de      ><a,"b",c     ><ab  >
<abcdefg><xyab,c,de ><xyzab "c" de   ><abc         ><abcd>

显然,我在每个字段周围添加了<>只是为了清楚每个字段的开始/结束位置,您将为实际应用删除它,我正在创建数组{ {1}}将每个字段的特定宽度保持为idk,否则将从中获取。

以上使用GNU awk进行FPAT,其他awks则是while(match())循环。

答案 2 :(得分:0)

如果要格式化逗号分隔文件(CSV),而不更改其内容(逗号分隔符除外),则可以使用以下命令:

column -t -s, file.csv

column命令将确定CSV文件中每列的最大长度,并填充空格以对齐数据。