1. http://cn.perlmaven.com/how-to-read-a-csv-file-using-perl
  2. http://search.cpan.org/~hmbrand/Text-CSV_XS-1.09/CSV_XS.pm
  3. 读取并处理文本是 Perl 的强项。有时候你有一个CSV (Comma-separated values)文件,需要从中提取信息,该怎么办呢?
  4. 本节给出三个解决方案。
  5. 如果你的CSV文件比较简单,简单的Perl脚本就能轻松搞定。这里是我们的方案一。
  6. 第二个方案能够对付稍微复杂的CSV文件。
  7. 第三个方案,能够处理所有的情况,不过,需要用CPAN上的模块。
  8. 假设我们有一文件,内容如下:
  9. Tudor,Vidor,10,Hapci
  10. Szundi,Morgo,7,Szende
  11. Kuka,Hofeherke,100,Kiralyno
  12. Boszorkany,Herceg,9,Meselo
  13. 这就是一个基本的CSV文件。每个数据项由逗号隔开(Comma-separated values),多行构成一个文件。
  14. 当然,分隔符不一定是逗号,只要保持一致就好了。不过通常是逗号隔开,也有是用 TAB 或者 | 键隔开。
  15. 我们要做的是算出第三列所有数字之和。
  16. 思路
  17. 按行读取文件
  18. 从读取的行中,取出第三列的值
  19. 累加
  20. 我们在以前的章节中学过怎样按行读取文件。下面我们来看怎样提取第三列的值。
  21. 你可能想到直接用substr(),不过,因为第三列的位置在每一行中不是固定的。那什么是不变的呢? 第三列的值总是在第二个逗号与第三个逗号之间。基于此,我们可以用index() 来得到每一行, 第二个和与第三个逗号的位置。然后再用substr()。不过,Perl中,有更好的方法。
  22. 用 split
  23. split() 的中文意思是分隔。要实现分隔的操作,你需要分隔符和要分的字符串。 分隔符可以是字符串,甚至是正则式。简单起见,我们只用字符串。
  24. 如果你有一个字符串$str = "Tudor:Vidor:10:Hapci",执行@fields = split(":" , $str);, @fields中将会有四个值, "Tudor", "Vidor", "10" and "Hapci"。print $fields[2]将会得到 10。 不要忘了,Perl 数组从 0 开始索引的。
  25. 对于我们的问题,用 @fields = split("," , $str); 就可以了。当然,split 后的 () 通常省略。
  26. 所以,完整的程序可以这样写:
  27. #!/usr/bin/perl
  28. use strict;
  29. use warnings;
  30. my $file = $ARGV[0] or die "Need to get CSV file on the command line\n";
  31. my $sum = 0;
  32. open(my $data, '<', $file) or die "Could not open '$file' $!\n";
  33. while (my $line = <$data>) {
  34. chomp $line;
  35. my @fields = split "," , $line;
  36. $sum += $fields[2];
  37. }
  38. print "$sum\n";
  39. 保存为csv.pl,在终端输入 perl csv.pl data.csv 就可以得到结果了。
  40. 万一有数据项中带逗号怎么办?
  41. 显然,我们的程序不能用了。
  42. 比如这个文件,完全符合CSV的格式规定。
  43. Tudor,Vidor,10,Hapci
  44. Szundi,Morgo,7,Szende
  45. Kuka,"Hofeherke, alma",100,Kiralyno
  46. Boszorkany,Herceg,9,Meselo
  47. 第三行,split后,第三列的值是 alma"。
  48. Text::CSV
  49. 好像有点复杂了,是吧,那好,求助 CPAN。幸运的是,Text::CSV 能够帮助我们。
  50. 解决上个问题的代码:
  51. #!/usr/bin/perl
  52. use strict;
  53. use warnings;
  54. use Text::CSV;
  55. my $csv = Text::CSV->new({ sep_char => ',' });
  56. my $file = $ARGV[0] or die "Need to get CSV file on the command line\n";
  57. my $sum = 0;
  58. open(my $data, '<', $file) or die "Could not open '$file' $!\n";
  59. while (my $line = <$data>) {
  60. chomp $line;
  61. if ($csv->parse($line)) {
  62. my @fields = $csv->fields();
  63. $sum += $fields[2];
  64. } else {
  65. warn "Line could not be parsed: $line\n";
  66. }
  67. }
  68. print "$sum\n";
  69. Text::CSV 是Perl的第三方扩展,帮助我们读写 CSV 文件。Perl 程序员把第三方扩展称为模块,有些语言中称为类库。
  70. 使用模块之前,需要先安装。我们已经讲过怎样安装模块,在这里不做赘述。
  71. 安装了模块以后,用use Text::CSV;来加载。
  72. Text::CSV 实际是一个类,可以用new来创建这个类的实例。-> 是调用的意思。
  73. my $csv = Text::CSV->new({ sep_char => ',' }); 创建了一个类的实例,通常称为对象。 Perl 中对象也是一个标量。事实上,可以省略 { sep_char => ',' } 因为,默认的分隔符(sep_char) 是逗号。
  74. 接下来,说说 split 和 $sum 所在的行。
  75. Text::CSV 模块没有split 函数,而是提供了 “parse 函数” ————在面向对象编程中,称为"parse 方法"。用箭头(->)来调用
  76. $csv->parse($line) 的意思是,解析 $line, 它并不直接返回解析的内容,而是告诉你解析是否成功, 比如,如果 $line 的内容是 Kuka,"Hofeherke, alma,100,Kiralyno,解析就会失败,因为这行的内容不符合 CSV的格式。
  77. 如果解析成功,我们可以调用 fields 方法,来取得解析的值。然后取出我们想要的那个。
  78. 一个数据项占据多行
  79. 比如:
  80. Tudor,Vidor,10,Hapci
  81. Szundi,Morgo,7,Szende
  82. Kuka,"Hofeherke,
  83. alma",100,Kiralyno
  84. Boszorkany,Herceg,9,Meselo
  85. 我们的上个解决方案又不行了。不过 Text::CSV 是可以解决这个问题的。
  86. 以下代码基于Text::CSV_XS 模块现任维护者的评论:
  87. #!/usr/bin/perl
  88. use strict;
  89. use warnings;
  90. use Text::CSV;
  91. my $file = $ARGV[0] or die "Need to get CSV file on the command line\n";
  92. my $csv = Text::CSV->new ({
  93. binary => 1,
  94. auto_diag => 1,
  95. sep_char => ',' # not really needed as this is the default
  96. });
  97. my $sum = 0;
  98. open(my $data, '<:encoding(utf8)', $file) or die "Could not open '$file' $!\n";
  99. while (my $fields = $csv->getline( $data )) {
  100. $sum += $fields->[2];
  101. }
  102. if (not $csv->eof) {
  103. $csv->error_diag();
  104. }
  105. close $data;
  106. print "$sum\n";
  107. 上例中,我们不再按行读取文件,而是打开文件后,交给Text::CSV 模块处理,我们通过 getline 来 得到需要的行。Text::CSV 会把占据多个行的数据项当作一个数据正确处理,而不是当作多行。
  108. 另外,getline 返回的并不是我们期望的数组,而是数组的引用。想要从数组的引用中得到第三项,用 $fields->[2]。我们以后会更详细的学习引用相关的知识。
  109. 如果读完CSV的数据项,正常情况下,应该是到了文件末尾。如果不是,那就是有问题,我们让程序输出诊断信息。

(转载)CSV 文件处理 PERL的更多相关文章

  1. 【转载】 C#工具类:Csv文件转换类

    CSV是逗号分隔值格式的文件,其文件以纯文本形式存储表格数据(数字和文本).CSV文件由任意数目的记录组成,记录间以某种换行符分隔:每条记录由字段组成,字段间的分隔符是其它字符或字符串,最常见的是逗号 ...

  2. [Excel] CsvHelper---C#关于CSV文件的导入和导出以及转化 (转载)

    点击下载 CsvHelper.rar 这个类是关于Csv文件的一些高级操作1.DataTable导出到CSV2.将Csv读入DataTable看下面代码吧 /// <summary> // ...

  3. 【Java/csv】一个CSV文件解析类(转载)

    /*下文写得不错,值得学习**/ import java.io.BufferedReader; import java.io.FileReader; import java.util.ArrayLis ...

  4. 【转载】JS导出CSV文件

    转自:http://www.cnblogs.com/dengnan/p/3990211.html 通过自己实际测试有以下几种方法 方法一通过a标签实现,把要导出的数据用“\n”和“,”拼接成一个字符串 ...

  5. 理解CSV文件以及ABAP中的相关操作

    在很多ABAP开发中,我们使用CSV文件,有时候,关于CSV文件本身的一些问题使人迷惑.它仅仅是一种被逗号分割的文本文档吗? 让我们先来看看接下来可能要处理的几个相关组件的词汇的语义. Separat ...

  6. C# .csv文件转为Excel格式;Excel格式转换为.csv

    using System; using System.Diagnostics; using System.IO; using System.Reflection; using System.Windo ...

  7. 利用php CI force_download($filename, $data) 下载.csv 文件解决文件名乱码,文件内容乱码

    利用php CI force_download($filename, $data) 下载.csv 文件解决文件名乱码,文件内容乱码 2014-07-31 12:53 1047人阅读 评论(0) 收藏  ...

  8. C语言处理CSV文件的方法(一)

    什么是CSV文件 CSV是 Comma-separated values (逗号分隔值)的首字母缩写,它通常是以逗号且不仅限于逗号分隔各个值,我们都叫他CSV. 看下面的例子: China, Shan ...

  9. php阅读csv文件类

    php处理csv文件类: http://www.php100.com/cover/php/540.html <?php define("CSV_Start", 0); def ...

随机推荐

  1. tomcat的部署

    零.服务器.Servlet容器.web容器 Servlet容器:能够运行Servlet的环境叫做Servlet容器 web容器:能够运行web应用的环境就叫做web容器 weblogic websph ...

  2. [BS-03] 统一设置UITabBarController管理的所有VC的tabBarItem图标文字的颜色大小等属性

    1. 统一设置UITabBarController管理的所有VC的tabBarItem图标文字的颜色大小等属性 . 统一设置UITabBarController管理的所有VC的tabBarItem图标 ...

  3. EF Code First教程-01 创建一个简单的Code First程序

    1 从nuget中搜索并添加EF 2 在app.config或web.config中添加数据库连接 <connectionStrings> <add name="conns ...

  4. linux type命令用法_转

    转自:http://codingstandards.iteye.com/blog/831504 在脚本中type可用于检查命令或函数是否存在,存在返回0,表示成功:不存在返回正值,表示不成功. $ t ...

  5. CL.exe的 /D 选项, Preprocessor Macro预处理器宏定义

    在看"Inside COM"第10章的代码. MAKEFILE里面有几个标记我没看懂. 去网上搜也搜不到. /D_OUTPROC_SERVER_ /DWIN32 /DREGISTE ...

  6. spring security之httpSecurity使用示例

    如果在HttpSecurity中配置需要authenticate(),则如果没有登陆,或没有相关权限,则会无法访问 2017-01-02 23:39:32.027 DEBUG 10396 --- [n ...

  7. ios常见细节问题-删掉main.storyboard程序启动屏幕变黑-崩溃

    删掉程序默认的main.storyboard文件后,程序启动崩溃 如图所示.原因是删掉main.storyboard文件后没有在info.plist文件里面设置 删掉main.storyboard后程 ...

  8. LUA闭包概念演示

    闭包的一个重要场景,形成一个自治的环境, 让操作可以封闭运行, 即函数运行时有状态的,可以从闭包创建时候的环境独立开来. 例如下面的lua闭包, genFilter 其入参parmIn是 函数的内部变 ...

  9. editplus3运行Python程序

    editplus3是一款不错的编辑器,他可以编译,运行java,php等各种程序,现把他运行Python程序的方法贴出来,首先得安装python,然后打开editplug3,工具——配置用户工具——组 ...

  10. android与后台请求的例子

    public static ClientResponse SendClientRequest(List<BasicNameValuePair> params){ ClientRespons ...