免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 4496 | 回复: 12
打印 上一主题 下一主题

perl 如何用数据文件的头文件字段匹配任意取数据列 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-08-13 13:12 |只看该作者 |倒序浏览
本帖最后由 liuxh_198308 于 2015-09-09 12:23 编辑

111111111111

论坛徽章:
0
2 [报告]
发表于 2015-08-13 13:18 |只看该作者
花费了1天时间研究,还是没弄出来,有高手帮忙吗 ?再下不胜感激 。

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
3 [报告]
发表于 2015-08-13 14:22 |只看该作者
本帖最后由 MMMIX 于 2015-08-13 14:23 编辑

回复 1# liuxh_198308

几点建议:
    1. 每个脚本都加上 use strict; 和 use warnings; 可以帮你检测及避免很多常见错误;
    2. 应该用现成的模块, 例如 Text::CSV, 来解析文件, 而不是自己手工解析;


至于你的问题, 你只要做个名字到列数的映射, 利用你现有的代码, 就完全可以解决了.

论坛徽章:
0
4 [报告]
发表于 2015-08-13 14:38 |只看该作者
回复 3# MMMIX


    谢谢你的回复,我现在test.SCV 不是手工解析的 ,列的提取是根据我写的代码来提取的, 之前输入的参数是 1,2,5,6 的,现在想输入字段与文件头的字段进行匹配取出列 ,我试过很多方法不行,能帮忙看一下嘛? 求解决 ,求大神 ,求高手!!救命啊。

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
5 [报告]
发表于 2015-08-13 14:50 |只看该作者
回复 4# liuxh_198308


    你可以参考下面的例子:

  1. #!/usr/bin/perl

  2. use strict;
  3. use warnings;

  4. use v5.14;
  5. use autodie;

  6. use Text::CSV;

  7. # Usage: ./p.pl input.csv FIELD1 [FIELD2 ...]

  8. my ($input, @fields) = @ARGV;

  9. open my $in_fh, '<', $input;

  10. my $csv = Text::CSV->new()
  11.     or die "Cannot use CSV: " . Text::CSV->error_diag();

  12. if (my $header = $csv->getline($in_fh)) {
  13.     $csv->column_names(@$header);
  14. } else {
  15.     die "No header line in $input";
  16. }

  17. while (my $line = $csv->getline_hr($in_fh)) {
  18.     say join ', ', map { $line->{$_} ? $line->{$_} : ' ' } @fields;
  19. }
复制代码
运行示例:

$ ./p.pl input.csv eNodeB date TIMESTAMP_MILLISEC
10.0.0.36-M11375, 20150730, 161
10.0.0.32-E11443, 20150730, 629
10.0.0.36-M11375, 20150730, 161
10.0.0.36-M11375, 20150730, 162
10.0.0.36-M11375, 20150730, 163

论坛徽章:
7
戌狗
日期:2013-12-15 20:43:38技术图书徽章
日期:2014-03-05 01:33:12技术图书徽章
日期:2014-03-15 20:31:17未羊
日期:2014-03-25 23:48:20丑牛
日期:2014-04-07 22:37:44巳蛇
日期:2014-04-11 21:58:0915-16赛季CBA联赛之青岛
日期:2016-03-17 20:36:13
6 [报告]
发表于 2015-08-14 01:39 |只看该作者
1 ge xiao lizi


perl abc.pl ./ test.CSV ./ , 1,2,3,4 3
perl abc.pl ./ test.CSV ./ , eNodeB,date,TIMESTAMP_SECOND,NONE,TIMESTAMP_MILLISEC 3
  1. #!/usr/bin/perl
  2. use 5.022;
  3. my @argv =
  4.   qw/数据源目录 文件名 转换目标目录 分隔符 提取字段列表 开始行/;
  5. die "usage: @argv\n" if @ARGV != @argv;

  6. my ( $dir, $file, $dir2, $sep, $list, $line ) = @ARGV;

  7. open my $DATA, '<', $dir . $file;
  8. open my $SAVE, '>', $dir2 . 'ConvertLog';

  9. my @list  = split ',', $list;
  10. my @field = these();

  11. convert();

  12. #### SUB ####

  13. sub these {
  14.     my $field = <$DATA>;
  15.     chomp $field;
  16.     split $sep, $field;
  17. }

  18. sub gimme {
  19.     return map { $_ - 1 } @list if $list[0] =~ /^\d+$/;
  20.     my %field = map { $_, $a++ } @field;
  21.     my $NA = keys %field;
  22.     map { $field{$_} // $NA } @list;
  23. }

  24. sub print_fields {
  25.     if ( $list[0] =~ /^\d+$/ ) {
  26.         say $SAVE join $sep, map { $_ // 'NA' } @field[@_];
  27.     }
  28.     else {
  29.         say $SAVE join $sep, @list;
  30.     }
  31. }

  32. sub convert {
  33.     my @index = gimme();
  34.     print_fields(@index) if $line < 2;
  35.     <$DATA> for 3 .. $line;

  36.     while (<$DATA>) {
  37.         chomp;
  38.         my @data = map /([^"]+)/, split $sep;
  39.         say $SAVE join ',', map { $_ // '' } @data[@index];
  40.     }
  41. }

  42. __DATA__
  43. eNodeB,date,HOUR,TIMESTAMP_MINUTE,TIMESTAMP_SECOND,TIMESTAMP_MILLISEC
  44. "10.0.0.36-M11375","20150730","2","45","9","161"
  45. "10.0.0.32-E11443","20150730","2","45","14","629"
  46. "10.0.0.36-M11375","20150730","2","45","9","161"
  47. "10.0.0.36-M11375","20150730","2","45","9","162"
  48. "10.0.0.36-M11375","20150730","2","45","9","163"
复制代码

论坛徽章:
0
7 [报告]
发表于 2015-08-14 11:03 |只看该作者
回复 5# MMMIX

谢谢了,这个受益匪浅 ,好好学习,天天向上!

   

论坛徽章:
0
8 [报告]
发表于 2015-08-14 11:06 |只看该作者
回复 6# rubyish


   我执行你代码,报错 ,第二行编译不通过  , use 5.022; 是什么东西,是版本还是模板 ?  

论坛徽章:
0
9 [报告]
发表于 2015-08-14 11:25 |只看该作者
回复 6# rubyish


    高手,use 5.022; 你这个里面包含了哪些模板包啊。

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
10 [报告]
发表于 2015-08-14 11:34 |只看该作者
回复 8# liuxh_198308


    use 5.022; 用来指定当前脚本需要的 perl 的最低版本为 5.22.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP