rahulme81 has asked for the wisdom of the Perl Monks concerning the following question:

0 down vote favorite My file contains 100 lines
1234 ABC 100.0.0.0 4567 DEF 200.0.0.0 .....
I am matching a pattern in my file. for example search for 4567 and replace the 200.0.0.0 to 500.0.0.0, so that line looks now 4567 DEF 500.0.0.0.
my $file = "$file_path/file.lst"; my $newid = "500.0.0.0" open MAST, $file or die "Unable to open file.lst: $!"; my $new = "$file.tmp.$$"; my $bak = "$file.bak"; open(NEW, "> $new") or die "can't open $new: $!"; while (<MAST>) { my ($pattern,$id) = (split /\s+/, $_)[0,4]; print $_; if ( $_ =~ m/^$pattern/ ) { $_ =~ s/$id/$newid/g; } (print NEW $_) or die "can't write to $new: $!"; } close(MAST) or die "can't close $file: $!"; close(NEW) or die "can't close $new: $!"; rename($file, $bak) or die "can't rename $file to $bak: $!"; rename($new, $file) or die "can't rename $new to $file: $!";
What i need to do : Show the line before change and after change on screen and ask for user confirmation and proceed with other things later. Please advice

Replies are listed 'Best First'.
Re: Perl file editing
by choroba (Cardinal) on Nov 04, 2015 at 10:02 UTC
    You crossposted the question to StackOverflow without telling us (well, if we don't take the 0 down vote favorite part as a hint). Crossposting is allowed, but you should inform us about the fact to save people not attending both sites from spending their time hacking a solution to the problem already solved at the other end of the internet.

    Also, instead of creating a new version of a question, you should edit the original one. Read How do I change/delete my post? for details.

    To show the neighbouring lines, you can use a "sliding window", i.e. always keep three lines in memory. If the middle one matches the criterion, show the other two and ask the user for confirmation.

    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: Perl file editing
by Athanasius (Archbishop) on Nov 04, 2015 at 10:22 UTC

    Hello rahulme81,

    Your while loop contains this line:

    my ($pattern,$id) = (split /\s+/, $_)[0,4];

    which sets $pattern and $id to the first and fifth fields, respectively, in the current line. But the data you show contains only three fields per line, so you should have:

    my ($pattern, $id) = (split /\s+/)[0, 2];

    (Note that the $_ is unnecessary here.) Also, this line:

    if ( $_ =~ m/^$pattern/ ) {

    tests whether the current line begins with $pattern. But you just initialized $pattern as the first field in the line, so how could this fail? (Well, it will fail if the line begins with whitespace, but I don’t think that’s what you had in mind.) You need to test $pattern against a pre-determined pattern, for example:

    ... my $pattern_to_find = '4567'; ... while (<MAST>) { my ($pattern, $id) = (split /\s+/)[0, 2]; ... if ($pattern eq $pattern_to_find) { ...

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,