Link to home
Start Free TrialLog in
Avatar of pehalwaan
pehalwaanFlag for Afghanistan

asked on

Deleting text in remote file through perl script

Little help required. I am trying to do same thing now on a remote file. i.e i want to delete lines from a remote file. below is the script. Can you please have a lokk in this why it's not working.
#!/usr/bin/perl

use File::Remote;
my $remote = new File::Remote;
my $count;

my $file="192.168.197.20:/home/file";
$^I='.old';
   $remote->open(FILE, "$file") or die $!;
   print unless $count=(/zone "abhi.com" {/ .. 0) and 1 < $count && $count <= 10;
   $remote->close(FILE);
Avatar of codeflux
codeflux
Flag of United States of America image

This doesn't seem right:

 $count=(/zone "abhi.com" {/ .. 0)

Are you doing a range from a regex to 0?  What's the error you're getting?
Avatar of pehalwaan

ASKER

I am not getting any kind of error. The script executes correctly but it doesn't go to the remote server and delete the content.
However, this script works fine on the local system.
1. Add 'use strict;' to your code.

2. Use Symbol to initialize the file handle(s) - otherwise you're gonna get this error:

 Bad usage of open(HANDLE, file) at a line

3. Actually read from the remote file

You're not reading any lines from remote file

4. Actually write remote file

You're not writing any lines to remote file

It would help if you posted input file and sample of output.
Something like this:
use Symbol;
my $infh = Symbol::gensym;
my $outfh = Symbol::gensym;
$remote->open($infh, $file) or die $!;
$remote->open($outfh, "$file.out") or die $!;
while(my $line = <$infh>) {
    print $outfh $line if $line !~ /zone "abhi.com" {/;
}
$remote->close($infh);
$remote->close($outfh);

Open in new window

Sorry, here's corrected code.  I don't understand your use of $count, so I omitted it from my example.

If you want new file to overwrite old one, you can use File::Remote::rename()
use strict;
use File::Remote;
use Symbol;
my $remote = new File::Remote;
my $infh = Symbol::gensym;
my $outfh = Symbol::gensym;
my $file="192.168.197.20:/home/file";
$remote->open($infh, $file) or die $!;
$remote->open($outfh, ">$file.out") or die $!;
while(my $line = <$infh>) {
    print $outfh $line if $line !~ /zone "abhi.com" {/;
}
$remote->close($infh);
$remote->close($outfh);

Open in new window

Thanks for the quick response. But the above doesn't work. It doesn't delete the line zone abhi.com from the remote file.

I want my script to search this pattern in a remote file and then deletes 6 lines after this pattern.,
OK, here you go:
use File::Remote;
    use Symbol;
    my $remote = new File::Remote;
    my $infh   = Symbol::gensym;
    my $outfh  = Symbol::gensym;
    my $file   = "192.168.197.20:/home/file";
    $remote->open($infh,  $file)        or die $!; 
    $remote->open($outfh, ">$file.out") or die $!; 
    while (my $line = <$infh>) {
        print $outfh $line;
        if ($line =~ /zone "abhi.com" {/) {;
            $line = <$infh> for 1 .. 6;  # read and ignore next 6 lines
        }   
    }   
    $remote->close($infh);
    $remote->close($outfh);
    # rename files around - not bullet-proof, but works.
    $remote->move($file, "$file.old");
    $remote->move("$file.out", $file);

Open in new window

No, The above script also doesn't works. The script goes to the remote server but doesn't search the given pattern and neither deletes 6 lines after it.
I just tested it, and it works for me.  Perhaps adding some debugging lines to the code will tell you what it's doing.
use File::Remote;
    use Symbol;
    my $remote = new File::Remote;
    my $infh   = Symbol::gensym;
    my $outfh  = Symbol::gensym;
    my $file   = "192.168.197.20:/home/file";
    $remote->open($infh,  $file)        or die $!; 
    $remote->open($outfh, ">$file.out") or die $!; 
    while (my $line = <$infh>) {
        print "DEBUG: read $line";
        print $outfh $line;
        if ($line =~ /zone "abhi.com" {/) {;
            print "DEBUG: found zone, skipping 6 more lines\n";
            $line = <$infh> for 1 .. 6;  # read and ignore next 6 lines
        }   
    }   
    $remote->close($infh);
    $remote->close($outfh);
    # rename files around - not bullet-proof, but works.
    $remote->move($file, "$file.old");
    $remote->move("$file.out", $file);

Open in new window

No doubt, the above code works  , but it doesn't deletes the lines from the file, it only skips the line in the output shown on the screen
After the script executes successfully, the lines still exists in the file.
That's why I added the two move() calls:

    $remote->move($file, "$file.old");
    $remote->move("$file.out", $file);

You can't rewrite the file on the fly (without making it overly complicated).  What you can do, however, is this:

- Make a remote copy of the file
- start reading that remote copy, overwriting the file.

However, the result will be the same: as soon as you open the remote file for writing, it'll empty it out:

    $remote->open($outfh, ">$file") or die $!; 

Open in new window


so if there is some other process that may read the file while you're writing it, it'll see an empty file.

Again, without context, it's hard to know what you're trying to do.  I believe I provided you with enough information to work with.
use File::Remote;
    use Symbol;
    my $remote = new File::Remote;
    my $infh   = Symbol::gensym;
    my $outfh  = Symbol::gensym;
    my $file   = "192.168.197.20:/home/file";
    $remote->copy($file, "$file.old");
    $remote->open($infh,  "$file.old") or die $!; 
    $remote->open($outfh, ">$file") or die $!; 
    while (my $line = <$infh>) {
        print "DEBUG: read $line";
        print $outfh $line;
        if ($line =~ /zone "abhi.com" {/) {;
            print "DEBUG: found zone, skipping 6 more lines\n";
            $line = <$infh> for 1 .. 6;  # read and ignore next 6 lines
        }   
    }   
    $remote->close($infh);
    $remote->close($outfh);

Open in new window

The two move calls that you are using doesn't work at all. the original file and the old file reminas same.
How ever according to you . the new file should not contain the 6 lines after the pattern.
Can you provide me with other code to solve my problem
 " I just want to run a scripts that runs and finds a pattern in a remote file and deletes the next 6 lines after the pattern"
ASKER CERTIFIED SOLUTION
Avatar of codeflux
codeflux
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
(make sure you have write-access to the remote file)