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 Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Replace first occurance in file 2

Status
Not open for further replies.

JimJx

Technical User
Feb 16, 2001
202
US
Hi all,

I read faq219-555 about doing a search and replace. However, it doesn't quite fit what I need to do and I am noit sure what needs to be modified.

The script will run through a file and replace all occurances of XXX. However, I have a file that is 100 lines long and has data similar to:

1111|0000|No
1112|0001|No
1113|0002|No

What I need to do is change the first occurance of the word No to Yes and save the entire file with that one change so I get:

1111|0000|Yes
1112|0001|No
1113|0002|No


Any suggestions will be greatly appreciated.
Jim
 
How about:
[tt]
open INF,'<infile' or die "Can't open input file";
open OUTF,'>outfile' or die "Can't open output file";
$changed=0;
for(<INF>)
{
if(!$changed)
{$changed=$_=~s/|No/|Yes/}
print OUTF $_;
}
close INF;
close OUTF;
[/tt]
 
Code:
{
   my $flag = 0;
   local($^I, @ARGV) = ('.bak', 'file.txt');
   while (<>) { 
      if (/^(.+)(\|No)$/ && $flag == 0) {
         $flag = 1; 
         print "$1|Yes\n";
      } 
      else {
         print;
      }
   }
}
 
Thanks guys!

Tony, when I ran yours, it put the |No at the beginning of the line. I changed the
Code:
{$changed=$_=~s/|No/|Yes/}
to
Code:
{$changed=$_=~s/No/Yes/}
and it worked on the first line.

However, it will not go past the first line with changes. To me, it looks like it should.

Any ideas?

Kevin, when I ran yours, it choked on the $^I and said 'Can't use global $^I in "my" at....'. And to be completely honest, I don't know enough about what you are doing to know what is going on with it.

Thanks again to both of you,
Jim
 
For Tony's first example the '|' has to be escaped since '|' is regex speak for "or" It should read:

$changed=$_=~s/\|No/\|Yes/


 
You must have changed something in the code I posted, as you can see I used 'local' on the globals:

local($^I, @ARGV) = ('.bak', 'file.txt');
 
ok, I did screw something up......

But now, it runs through the whole file, ~100 entries, and changes all of the No to Yes.....

I copied and pasted directly again:
Code:
   my $flag = 0;
   local($^I, @ARGV) = ('.bak', 'file.txt');
   while (<>) {
      if (/^(.+)(\|No)$/ && $flag == 0) {
         $flag = 1;
         print "$1|Yes\n";
      }
      else {
         print;
      }
   }
 
cfmartin2000 is right, the |s need to be escaped. Other than that, my code should work.
 
If you are using the code recursively you have to reset the flag back to 0 when you open a new file. If you mean it changes all lines in the same file to 'Yes', I don't know why that is. It worked fine for me when I tested the code.
 
I don't know why the page wasn't working with either of the solutions you guys posted. So, I redid the whole page, thankfully it was still very small. After that, either solution worked, so you both get stars.

Kevin, I eventually decided to go with your solution. But 1 more quick qusetion. How do I run a split in the while (<>) section to grab the info in there into a string?

Thanks again to both of you,
Jim
 
Your question is very general so I answered it in a general way:

Code:
{
   my $flag = 0;
   local($^I, @ARGV) = ('.bak', 'file.txt');
   while (<>) {
      [b]my ($V1, $V2, $V3) = split(/\|/);[/b] 
      if (/^(.+)(\|No)$/ && $flag == 0) {
         $flag = 1;
         print "$1|Yes\n";
      }
      else {
         print;
      }
   }
}
 
Never mind, I got it after the momentary lapse of reason ended....

Thanks!
Jim
 
>> Never mind, I got it after the momentary lapse of reason ended....

[upsidedown]
 
I don't know what is going on, but now using this script, it is grabbing 2 entries to the file and changing them. Using the example above, instead of getting

1111|0000|Yes
1112|0001|No
1113|0002|No

I am getting

1111|0000|Yes
1112|0001|Yes
1113|0002|No

Other then grabbing some vars at the beginning, here is the complete script that I am using....

Code:
my ($Name, $Pass, $Used);

my $flag = 0;
   local($^I, @ARGV) = ('.bak', 'user.txt');
   while (<>) {
      if (/^(.+)(\|No)$/ && $flag == 0) {
         $flag = 1;
         print "$1\|Yes\n";
         ($Name, $Pass, $Used) = split (/\|/);
      }
      else {
         print;
      }
   }

open (PAGE, "$newUser") or die ("Unable to open the file newUser. $!");
     while (<PAGE>)                
     {
        s/%%name%%/$Name/g;
        s/%%pass%%/$Pass/g;
        print $_;
}
close (PAGE);

Thanks for any help,
Jim
 
looks OK to me:

1111|0000|Yes
1112|0001|No
1113|0002|No

I am getting

1111|0000|Yes
1112|0001|Yes
1113|0002|No

the first set of lines above there is already one Yes, in the next set of lines there is one more Yes. So the script changed one instance of Yes to a No.

- Kevin, perl coder unexceptional!
 
Sorry, that is my bad on the post.....

What I am actually getting (The second group in my example)

1111|0000|Yes
1112|0001|Yes
1113|0002|Yes

What I expect to see is
1111|0000|Yes
1112|0001|Yes
1113|0002|No
 
works OK for me:

Code:
my $flag = 0;
while (<DATA>) {
   if (/^(.+)(\|No)$/ && $flag == 0) {
      $flag = 1;
      print "$1\|Yes\n";
      my ($Name, $Pass, $Used) = split (/\|/);
   }
   else {
      print;
   }
}
__DATA__
1111|0000|Yes
1112|0001|Yes
1113|0002|Yes
[b]1111|0000|No[/b]
1112|0001|No
1113|0002|No
1111|0000|No
1112|0001|No
1113|0002|No

outputs:

Code:
1111|0000|Yes
1112|0001|Yes
1113|0002|Yes
[b]1111|0000|Yes[/b]
1112|0001|No
1113|0002|No
1111|0000|No
1112|0001|No
1113|0002|No

- Kevin, perl coder unexceptional!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top