打开两个文本文件,处理它们并写入单独的文件

时间:2017-10-13 17:32:45

标签: perl file output

我正在使用Perl打开两个文本文件,处理它们然后将输出写入另一个文件。

我有一个文件INPUT,每一行都是客户。我将处理每一行变量,用于替换另一个文件TEMP中的文本。结果应写入每个客户的单个文件OUTPUT

我的程序似乎只在第一个文件上工作。其余文件保持为空,没有输出。

#!/usr/bin/perl -w

if ( $#ARGV < 0) {
    print "Usage: proj5.pl <mm/dd/yyyy>\n";
    exit;
}

my $date = $ARGV[0];

open(INFO, "p5Customer.txt") or die("Could not open p5Customer.txt file\n");
open(TEMP, "template.txt")   or die("Could not open template.txt file\n");

my $directory = "Emails";
mkdir $directory unless(-e $directory);

foreach $info (<INFO>){

    ($email, $fullname, $title, $payed, $owed) = split /,/, $info;
    next if($owed < $payed);
    chomp($owed);

    $filepath = "$directory/$email";
    unless(open OUTPUT, '>>'.$filepath){
        die "Unable to create '$filepath'\n";
    }

    foreach $detail (<TEMP>){
        $detail =~ s/EMAIL/$email/g;
        $detail =~ s/(NAME|FULLNAME)/$fullname/g;
        $detail =~ s/TITLE/$title/g;
        $detail =~ s/AMOUNT/$owed/g;
        $detail =~ s{DATE}{$date}g;
        print OUTPUT $detail;
    }

    close(OUTPUT);
}

close(INFO);
close(TEMP);

2 个答案:

答案 0 :(得分:0)

你的问题是TEMP循环 INPUT循环内部,因此当INPUT循环仍在INPUT文件的第一行时,TEMP循环将结束。

最好将TEMP文件数据存储到哈希表中,并处理INPUT循环内的TEMP哈希表。

祝你好运。

答案 1 :(得分:0)

如前所述,每次阅读时都需要再次打开模板文件。您的代码还存在许多其他问题

  • 始终 use strictuse warnings 'all'并声明每个变量my尽可能接近首次使用的位置

    < / LI>
  • $#ARGV@ARGV的最后一个元素的索引,因此$#ARGV < 0更好地写为@ARGV < 1

  • 您应该使用 lexical 文件句柄,以及open的三参数形式,因此open(INFO, "p5Customer.txt")应为open my $info_fh, '<', "p5Customer.txt"

  • 您应该使用while代替for来读取文件

  • 使用默认变量$_更容易进行短循环

  • 如果你不打算使用正则表达式中的子字符串是没有意义的,那么(NAME|FULLNAME)应该是NAME|FULLNAME

  • 在程序结束前关闭输入文件没有意义

使用现有的模板系统也好得多,例如 Template::Toolkit

这应该对你有用

#!/usr/bin/perl

use strict;
use warnings 'all';

if ( @ARGV < 1 ) {
    print "Usage: proj5.pl <mm/dd/yyyy>\n";
    exit;
}

my $date = $ARGV[0];

open my $info_fh, '<', 'p5Customer.txt' or die qq{Could not open "p5Customer.txt" file: $!};

my $directory = "Emails";
mkdir $directory unless -e $directory;

while ( <$info_fh> ) {

    chomp;
    my ($email, $fullname, $title, $payed, $owed) = split /,/;
    next if $owed < $payed;

    open my $template_fh, '<', 'template.txt' or die qq{Could not open "template.txt" file: $!};

    my $filepath = "$directory/$email";
    open my $out_fh, '>', $filepath or die qq{Unable to create "$filepath": $!};

    while ( <$template_fh> ) {

        s/EMAIL/$email/g;
        s/FULLNAME|NAME/$fullname/g;
        s/TITLE/$title/g;
        s/AMOUNT/$owed/g;
        s/DATE/$date/g;

        print $out_fh $_;
    }

    close($out_fh);
}