Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

Re: While loop not printing anything after using grep

by shmem (Chancellor)
on Dec 30, 2020 at 00:24 UTC ( [id://11125958]=note: print w/replies, xml ) Need Help??


in reply to While loop not printing anything after using grep

My ultimate gall here is to search for the string 'Friday' in the file 'input.txt', if 'Friday' is missing, add'Friday' to 'input.txt on line 2.

Just do it! But first a code review.

#!/bin/perl use strict; use warnings; my $input_file = 'input.txt'; open(my $in_file,'<',$input_file) or die "Can not open file $input_fil +e for reading: $!.\n"; if (grep{/Friday/} $in_file) { # WRONG. You are grepping the filehandl +e, # not the content of the file. print "Match\n"; } else { print "No match\n"; } print "Before\n"; # "Before" is long ago. while (<$in_file>) { print; # you don't look for "Friday" looping li +nes. } print "After\n"; # after "After" nothing happens but file + closing. close($in_file);

A filehandle is a filehandle, not the content of the file. In the while-loop you read the file line-wise, but you don't do anything but printing what you've read. Also, you don't look for line number 2. The line number read is stored in the perl special variable $. which you should test, if you want to add (append?) the string "Friday" to line two. Fix:

#!/bin/perl use strict; use warnings; my $input_file = 'input.txt'; open(my $in_file,'<',$input_file) or die "Can not open file $input_fil +e for reading: $!.\n"; while (<$in_file>) { if (/Friday/) { warn "match on line $.\n"; # warn goes to STDERR } elsif ($. == 2) { # no match on line 2 chomp; # remove line ending $_ .= "Friday\n"; # add "Friday" and line ending warn "added 'Friday' to line $.\n"; } print; } close($in_file);

If you want inplace edit, you can place the directives for that after the first line of the script and omit the file opening and the while()-loop as well as the print statement. See perlrun. Read that.
This edits your 'input.txt' file in-place, moving the original to 'input.txt.bak' first:

#!/bin/perl -l -pi.bak use strict; use warnings; if (/Friday/) { warn "match on line $.\n"; # warn goes to STDERR } elsif ($. == 2) { # no match but on line 2 $_ .= "Friday"; # add "Friday" (and line endin +g via -l) warn "added 'Friday' to line $.\n"; # warn doesn't add line ending + via -l }

Hope that helps (HTH).

perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'

Replies are listed 'Best First'.
Re^2: While loop not printing anything after using grep
by skjeiu (Novice) on Dec 30, 2020 at 14:13 UTC


    Following the constructive feedback here is the working code:

    #!/bin/perl use strict; use warnings; my $input_file = 'input.txt'; my $output_file = 'output.txt'; open(my $in_file,'<', $input_file) or die "Can not open file $input_fi +le for writing: $!.\n"; open(my $out_file,'>', $output_file) or die "Can not open file $output +_file for writing: $!.\n"; if (not (grep{/Monday/} <$in_file>) { seek $in_file, 0, 0; $. = 0; while (<$in_file>) { print $out_file $_; if ($. == 1) { print $out_file "Friday\n"; } } } close($in_file); close($out_file);


    The same code but with 'unless' instead of 'if (not)'

    #!/bin/perl use strict; use warnings; my $input_file = 'input.txt'; my $output_file = 'output.txt'; open(my $in_file,'<', $input_file) or die "Can not open file $input_fi +le for writing: $!.\n"; open(my $out_file,'>', $output_file) or die "Can not open file $output +_file for writing: $!.\n"; unless (grep{/Monday/} <$in_file>) { seek $in_file, 0, 0; $. = 0; while (<$in_file>) { print $out_file $_; if ($. == 1) { print $out_file "Friday\n"; } } } close($in_file); close($out_file);


    As 'seek' could probably be avoided if I rethink things in a different way, I'll get back to this when I have clarified my thoughts


    I appriciated

      open(my $in_file,'<', ...) or die "Can not open ... for writing: $!.\n";

      <nit>
      $in_file is being opened for reading ('<'), not writing.
      </nit>


      Give a man a fish:  <%-{-{-{-<

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11125958]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (6)
As of 2024-04-19 11:22 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found