如何使用Perl基于另一个文件的列内容修改特定列?

时间:2018-02-09 06:14:11

标签: perl

我想根据file2的column2修改file1的column3。找到column4和column3之间的file1差异(例如302.48-301.85),称为'diff',file2的column2和column3的总和(例如292.73 + 1.38)称为'total'。如果file1的column4值大于file2的总和,则找到file1的column3和名为diff1的总值之间的差异。 if(diff1< diff)然后通过file2的column2值修改file1的column3值。

我的问题是file1未被修改,显示:

en_4156 A en_4156_A **301.85 302.48** <O,en,F,en-F>  OH YEAH

而不是:

en_4156 A en_4156_A 299.22 302.48 OH YEAH

File1

;; LABEL "SW-F" "Switchboard Female" "Switchboard Female Caller"
;; LABEL "SW-M" "Switchboard Male" "Switchboard Male Caller"
en_4156 A en_4156_A 301.85 302.48 <O,en,F,en-F>  OH YEAH

File2

en_4156 A 292.73 1.38 i 1.00
en_4156 A 294.14 1.62 know 1.00
en_4156 A 296.09 2.64 what 0.55
en_4156 A 299.22 2.58 oh 1.00
en_4156 A 301.80 1.83 yeah 1.00
en_4156 A 303.91 0.84 well 0.95

更新了File1

;; LABEL "SW-F" "Switchboard Female" "Switchboard Female Caller"
;; LABEL "SW-M" "Switchboard Male" "Switchboard Male Caller"
en_4156 A en_4156_A 299.22 302.48 <O,en,F,en-F>  OH YEAH

代码:

#!/usr/bin/perl

my ($ctm, $stm)=@ARGV;
open(CTM, "<$ctm");
open(STM, "+<$stm");
while (<CTM>) {
    ($wav, $channel, $start, $duration, $word, $score)=split(" ", $_);
    push @wav_c, $wav;
    push @channel_c, $channel;
    push @start_c, $start;
    push @dur_c, $duration;
    push @words, $word;
    push @scores, $score;
}
while (<STM>) {
    @line=split(" ", $_);
    push @wav_s, $line[0];
    push @channel_s, $line[1];
    push @start_s, $line[3];
    push @end_s, $line[4];
}
$ls=scalar @start_s;
$lc=scalar @start_c;

$j=0;

for ($i=0; $i<$ls; $i++) {
    while ($wav_s[$i] eq ";;") {
        $i++;
    }
    $diff=$end_s[$i]-$start_s[$i];
    while (($wav_s[$i] eq $wav_c[$j]) && ($channel_s[$i] eq $channel_c[$j])) {
        $total=$start_c[$j]+$dur_c[$j];
        if ($end_s[$i] > $total) {
            $diff1=$start_s[$i]-$total;
            if ($diff1 <= $diff) {
                $start_s[$i]=$start_c[$j];
                $j++;
            }
            else {
                $j++;
            }
        }
        else {
            $j++;
        }
  }
}

1 个答案:

答案 0 :(得分:0)

将所有数据读入数组,然后尝试对数据执行所需的数学运算,然后写入文件太繁琐了。当您从文件中读取行时,执行计算会更容易。

我的结果文件:

$ cat results.txt 
;; LABEL "SW-F" "Switchboard Female" "Switchboard Female Caller"
;; LABEL "SW-M" "Switchboard Male" "Switchboard Male Caller"
en_4156 A en_4156_A 299.22 302.48 <O,en,F,en-F> OH YEAH

代码:

use strict;
use warnings; 
use 5.020;
use autodie;
use Data::Dumper;

my($file1, $file2, $results) = ('f1.txt', 'f2.txt', 'results.txt');
open my $FILE1, '<', $file1;
open my $FILE2, '<', $file2;
open my $RESULTS, '>', $results;

LINE_FILE1:
while(my $linef1 = <$FILE1>) {

    if($linef1 !~ /\Aen_\d{4}/) {  #if not a data line ...
        print {$RESULTS} $linef1;
        next LINE_FILE1;
    }

    my @colsf1 = split /\s+/, $linef1;
    my $diff = $colsf1[4] - $colsf1[3];

    while (my $linef2 = <$FILE2>) {
        my @colsf2 = split /\s+/, $linef2;
        my $total = $colsf2[2] + $colsf2[3];

        if($colsf1[4] > $total) {
            my $diff1 = $colsf1[3] - $total;
            $colsf1[3] = $colsf2[2] if $diff1 < $diff;
        }    
    }

    say {$RESULTS} "@colsf1";
}

close $FILE1;
close $FILE2;
close $RESULTS;