Perl:如果找到匹配项,如何插入一行?

时间:2021-01-20 08:05:05

标签: perl

文件内容:

456 name1 name2 345 678
423 name3 name4 345 678
435 name5 name6 345 678
866 name7 name8 345 678

插入行后的文件内容

456 name1 name2 345 678
423 name3 name4 345 678
Name3_Found
435 name5 name6 345 678
866 name7 name8 345 678

我得到的文件内容:

456 name1 name2 345 678
423 name3 name4 345 678
Name3_Found
me6 345 678
866 name7 name8 345 678

代码

open (temp2, "+<$file") or die "Could not open file";
my $point;
   
while(my $lin =<temp2>) {
    $point = tell(temp2);
    if ( $lin =~ /name5/ ){
        seek(temp2,$point-2,0);
        chk: 
        while (my $lin =<temp2>){
            my @rw = split" ",$lin;
            if ($rw[1] eq "name3"  ) {
                say temp2 "Name3_Found";
            } elsif( $lin =~ /name5/){
                last chk;
            }
        }
    }
}
close temp2;

有人知道为什么要删除其他行数据吗?以及如何修复它?

2 个答案:

答案 0 :(得分:2)

你在这里混合了一些东西。当您写入混合模式文件句柄 (+<) 时,您不是在插入数据。您正在覆盖已有的内容。

如果您有固定长度的记录并且想要获取特定记录,请使用 seek。要替换一条记录,您必须写出完全相同数量的八位字节。如果你写的八位字节太少,你会留下前一条记录的八位字节,如果你写的太多,你会覆盖下一条记录。

如果你想做面向行的东西,不要做混合模式open。打开文件读取它,并输出到一个新文件。 perlfaq5 covers this in "How do I change, delete, or insert a line in a file, or append to the beginning of a file?"

我认为 Learning Perl, 4th Edition 仍有一章介绍这方面的内容。

答案 1 :(得分:0)

仅仅因为你问,“......以及如何解决它?”

#!/usr/bin/env perl

use Data::Dumper;
use Hash::Util qw(lock_keys);
use strict;
use warnings;

my $file=q{TheData.txt};

# using three argument open and dying with error
open (my $temp, "+<",$file)
    or die "Could not open '$file'! $!";
my %ptr_h=(READER=>tell $temp,WRITER=>tell $temp);
# The only keys we're going to use are READER and WRITER --- anything will error out
lock_keys(%ptr_h);

# Our buffer
my @buffer_a;
while(my $line=<$temp>) {
    # The next read will start here
    $ptr_h{READER}=tell($temp);

    # Make any changes to the line - pushing them onto the buffer
    if ($line =~ m{name3}) { # only if name3
        # pushing them onto the buffer
        push @buffer_a,$line.qq{Name3_Found\n};
        }
    else { # otherwise just save it!
        push @buffer_a,$line;
        }
    # end of changes

    # Do we have anything to write and the room to write it
    while (@buffer_a && length($buffer_a[0]) <= $ptr_h{READER}-$ptr_h{WRITER}) {
        # We do have room to write the first record of the buffer
        seek $temp,$ptr_h{WRITER},0;
        # Enough room to write $Buffer_a[0] so write it ...
        print $temp shift(@buffer_a);
        $ptr_h{WRITER}=tell($temp);
        };
    }
# Go back to where we were reading
continue {
    seek $temp,$ptr_h{READER},0;
    };
# We've read and processed all of the file
# ... now write out what remains of the buffer
seek $temp,$ptr_h{WRITER},0;
while (@buffer_a) {
    print $temp shift(@buffer_a);
    };
# ... and truncate the file
truncate $temp,tell($temp);
# ... and close
close($temp)
    or die "Can't close '$file'! $!";

ACHTUNG:如果在您的更新过程中发生了什么事情,您可能会“在没有桨的情况下”。

相关问题