Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Edit an existing file using Perl

Status
Not open for further replies.
Apr 30, 2003
56
US
I have a file called oratabtest. The content of the file as follows:
atest:/apps/oracle/product/9.2.0:Y
btest:/apps/oracle/product/9.2.0:Y
ctest:/apps/oracle/product/9.2.0:Y
dtest:/apps/oracle/product/9.2.0:Y


I need to write a perl script to read into the file and if ctest then change the Y to N without modify other lines. So far, I come up with the following:

#!/usr/bin/perl
open (REPORT, ">oratabtest")||die "Can't open report file!\n";
COUNTERLOOP:while ($line = <REPORT>) {
chomp($line);
$a1=substr($line, 0, 5);
$a2=substr($line, 33, 1);
if ($a1 eq "ctest"){
substr($line, 33, 1, "N") if ($a2 eq "Y");
}
print "$line\n"; #for debugging
}
close (REPORT);

Well, apparently what I wrote does not work. I am not sure if any body has any idea about this? Thanks for your help.
 
Code:
#!/usr/bin/perl
use strict;
my $text;
open (RPT, "<oratabtest.txt") or die "Can't open report file, $!.\n";
while (<RPT>) { $text .= $_; }
close (RPT);

$text =~ s/(\x63\x74\x65\x73\x74:.*?:)Y/\1N/gs;
print "$text\n";

With a little obfuscation for fun... ;-)

'hope this helps

If you are new to Tek-Tips, please use descriptive titles, check the FAQs, and beware the evil typo.
 
Code:
my $fileToRead = 'oratabtest';
{ 
   local ($^I, @ARGV) = ('.bak', $fileToRead); 
   while (<>) { 
      if (/^ctest:/apps/oracle/product/9.2.0:Y$/) {
         print "ctest:/apps/oracle/product/9.2.0:N\n";
      }
      else {
         print;
      }
   } 
}
 
Well, thanks for your input. I tried your recommendation. After I ran the script, I check the oratabtest file. The original file is still left unchanged.
 
I just have it printing to STDOUT. You just need to open an output file to print to and then print to that handle.

'hope this helps

If you are new to Tek-Tips, please use descriptive titles, check the FAQs, and beware the evil typo.
 
You could try something like this:
Code:
my $file = 'oratabtest.txt'
open FILE, "< $file" or die;
my @lines = <FILE>;
open FILE, "> $file" or die;

foreach (@lines) {
    if (substr($_,0,5) eq 'ctest') {
        s/:Y(?=\s*$)/:N/;
    }
    print FILE;
}
Perl automatically closes the file when the file handle is reused, so there's no need for an explicit close.

You could get away with using a one-liner on this though:
Code:
perl -pi.bak -e "if (substr($_,0,5) eq 'ctest') { s/:Y(?=\s*$)/:N/; }" oratabtest.txt
 
I was looking for a problem I was having and saw yours.
I liked your original solution approach because it is more clear to newbies. It should work if you make the nested "if"
statements. You had it backward.

if ($a1 eq "ctest")
{
if ($a2 eq "Y")
{
substr($line, 33, 1, "N");
{
}

A better solution if the last character is always only
"Y" or "N" is the following.

if ($a1 eq "ctest")
{
substr($line, 33, 1, "N");
}

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top