2013-11-27 294 views
0

所以最近我每个月都会在工作中对患者进行验证检查。需要几天到过去几个月的验证与当前月份的比较:比较两个CSV文件并生成第三个文件

SeptemberVal.CSV

Gender MRN  Operation  Consultant TCI Date ... ... ... 
    Male 738495  CIRC  Dr Yates 05.12.13 ... ... ... 
    Female 247586 Cystoscopy Dr Know  10.12.13 ... ... ... 
    Male 617284  Biopsy  Dr Yates 25.12.13 ... ... ... 

OctoberVal.CSV

Gender MRN  Operation  Consultant TCI Date ... ... ... 
    Male 491854  Biopsy  Dr Yates 05.12.13 ... ... ... 
    Female 247586 Cystoscopy Dr Know  10.12.13 ... ... ... 
    Female 285769  Biopsy  Dr Yates 25.12.13 ... ... ... 
    ...  ...   ...   ...   ...  ... ... ... 

Output.csv

Gender MRN  Operation  Consultant TCI Date ... ... ... 
    Female 247586 Cystoscopy Dr Know  10.12.13 ... ... ... 
    ...  ...  ...   ...   ...  ... ... ... 

我想创建一个perl脚本,用于比较SeptermberVal.csv和“OctoberVal.csv”的“MRN”列和n一旦找到匹配项,我希望它将来自SeptemberVal.CSV的整个匹配行复制并粘贴到新文件中。

每个验证表格可能有800位患者,而且很多可以从前一个月继续,因此下个月我会说有900位患者验证400可能是以前的形式,其余的都是新的。

这是可能的Perl,如果是这样我会去呢?如果有人有如何做到这一点的任何示例代码,我将不胜感激。我想从长远来看选择Perl,因为它在工作社区中广泛使用。

+0

文件是否包含制表符分隔的数据? – Kenosis

+0

存在[CSV的DBD驱动程序](http://search.cpan.org/~hmbrand/DBD-CSV-0.41/lib/DBD/CSV.pm)文件,它也支持SQL连接。 – ceving

+0

@Kenosis我相信主要是逗号。 – Marshal

回答

0

你应该尝试的unix命令join

join,您可以:

  • 选择字段分隔符(逗号);
  • 选择用于连接(2)的字段;
  • 格式输出(行从SeptemberVal.CSV)
0

在这里你去 - 这应该为你做它非常精美,很容易读取和修改过。

#!/usr/bin/perl 
################################################################################ 
# File: ProcessMRNs 
# Author: Mark Setchell 
# stackoverflow.com/questions/20251625/perl-comparing-two-csv-files-and-producing-a-third 
################################################################################ 
use strict; 
use warnings; 
use Data::Dumper; 

    my $Debug=0; # Set to 1 for debug output 

    # Check user has supplied last month and this month's CSV file 
    if($#ARGV !=1){ 
     print "Usage: $0 <last_monthCSV> <this_monthCSV>\n"; 
     exit 1; 
    } 

    # Pick up CSV filenames from parameters 
    my $lastmonth=$ARGV[0]; 
    my $thismonth=$ARGV[1]; 

    # Hash to keep last month's records in, indexed by MRN 
    my %prevMRNs; 
    my $header; 

    # Open last month's file and read into hash indexed by MRN 
    my $MRN; 
    open(FH,"<",$lastmonth) or die "Unable to open $lastmonth"; 
    while(<FH>){ 
     chomp;    # Remove end of line junk 
     (undef,$MRN,undef)=split(" "); # Extract MRN from line 
     # Save table header if this is it 
     if($MRN =~ /MRN/){ 
      $header=$_; 
      next; 
     } 
     print "DEBUG: Read last month MRN:$MRN\n" if $Debug; 
     # Save this MRN into our hash of records, indexed by MRNs 
     $prevMRNs{$MRN}=$_; 
    } 
    close FH; 

    # Show user what we got from last month's CSV 
    print Dumper \%prevMRNs if $Debug; 

    # Now open this month's file 
    open(FH,"<",$thismonth) or die "Unable to open $thismonth"; 
    print "$header\n"; 
    while(<FH>){ 
     chomp;    # Remove end of line junk 
     (undef,$MRN,undef)=split(" "); # Extract MRN 
     next if $MRN =~ /MRN/;  # Ignore header line 
     print "DEBUG: Read current month MRN:$MRN\n" if $Debug; 
     # THIS IS THE CRITICAL LINE IN THE WHOLE SCRIPT 
     # If we saw this MRN last month, print what we saw 
     print "$prevMRNs{$MRN}\n" if defined $prevMRNs{$MRN}; 
    } 
    close FH; 

这里是没有调试输出:

Gender MRN  Operation  Consultant TCI Date ... ... ... 
    Female 247586 Cystoscopy Dr Know  10.12.13 ... ... ... 

下面是调试输出:

DEBUG: Read last month MRN:738495 
DEBUG: Read last month MRN:247586 
DEBUG: Read last month MRN:617284 
$VAR1 = { 
      '247586' => ' Female 247586 Cystoscopy Dr Know  10.12.13 ... ... ...', 
      '617284' => ' Male 617284  Biopsy  Dr Yates 25.12.13 ... ... ...', 
      '738495' => ' Male 738495  CIRC  Dr Yates 05.12.13 ... ... ...' 
     }; 
    Gender MRN  Operation  Consultant TCI Date ... ... ... 
DEBUG: Read current month MRN:491854 
DEBUG: Read current month MRN:247586 
    Female 247586 Cystoscopy Dr Know  10.12.13 ... ... ... 
DEBUG: Read current month MRN:285769 

假设你将它保存为 “ProcessMRNs”,你做这个运行:

chmod +x ProcessMRNs 
./ProcessMRNs september.csv october.csv 

如果你希望输出到文件而不是屏幕,添加“>输出。TXT”像这样的结尾:

./ProcessMRNs september.csv october.csv > output.txt 
+0

这个工作适合你吗?如果是这样,你可以用一个可爱的大绿蜱接受我的答案吗?如果不是,请说出错的地方,以便我/他人可以进一步帮助您。 –

0

只是为了好玩,这里是另一个(简单)答案:

awk 'FNR==NR{a[$2]=$0;next}{if ($2 in a)print a[$2]}' september.csv october.csv 

与结果:

Gender MRN  Operation  Consultant TCI Date ... ... ... 
Female 247586 Cystoscopy Dr Know  10.12.13 ... ... ... 

这工作完全一样Perl解决方案,但使用awk的关联数组(如Perl的哈希),也是处理2个输入文件的技巧,即september.csv和october.csv。

“FNR == NR”部分(直到“下一个”)适用于处理第一个文件,并且对于它在该文件中找到的每个记录,它将整个记录($ 0)保存在关联数组中(“a “)由MRN索引(2场,或2美元)。然后(从“if”开始)它处理第二个文件(october.csv)并且说“如果这个MRN(字段2或$ 2)在数组”a“中(从第一遍到september.csv )然后打印任何行中,我们发现了这个MRN在这一点上。

0

如何是你的Perl?

首先,你应该使用类似Text::ParseWordsText::CSV在你的文件中读取。这两种处理栏目化文件并处理引号。Text::CSV是最流行的,但Text::ParseWords自带Perl,所以它始终可用。

是否MRN每个文件都是唯一的编号?如果是这样,您可能希望将其作为密钥用于您的数据结构。你将不得不知道如何在Perl中使用引用,所以如果你不了解Perl引用,请阅读tutorial

认为你的文件的每一行由MRN号码被键入,每行作为参考,以另一种散列,其中每列由列的名称键控的:

$october{738495}->{gender}  = "M"; 
$october{738495}->{operation} = "CIRC"; 
$october{738495}->{consultant} = "Dr Yates"; 
$october{738495}->{tci_date} = "05.12.13"; 

现在,你可以通过这个结构,九月,拉,如果你有同年10 MRI

for my $mri (sort keys %september) { 
    if (exists $october{$mri}) {  # Similar MRI found in September and October 
     if ($september{$mri}->{gender} eq $october{$mri}->{gender} 
      and $september{$mri}->{consultant} eq $september{$mri}->{consultant} 
      ...) { 
      .... 
     else { 
      .... 
     } 
    } 
} 

如果你知道面向对象的Perl,你应该使用,并帮助恢复正常的东西像性别和顾问姓名,日期等。

相关问题