By default m// handles single line, even if some line containes \n in the line. The ^ $ symbols means the start and end to the whole characters, no matter it's a single line or multiple lines.
 
/m can make it works as there're multiple lines in the characters.
 
$_="I'm much better\nthan Barney is\nat bowling,\nWilma,\n";
print "Found 'wilma' at start of the line\n" if /^wilma\b/im;
 
We can read a whole file into a string and use /m to handle the multiple lines in it.
 
$filename="fred.txt";
open FILE, $filename
 or die "Can't open '$filename':$!";
my $lines=join "", <FILE>;
$lines=~s/^/$filename: /gm;
print "$lines\n";
 
It will appends '$filename: ' to each line of the file, like:
 
fred.txt: fred lintstone wilma some
fred.txt: Fred welsen.
fred.txt: FRED
fred.txt: wilma's friend fredrick jack
fred.txt: Alfred something
fred.txt: Mr. slate
fred.txt: okay
fred.txt: How are you guys?
fred.txt: LOL. good
 
We usually update many similar files, perl can make it easy.
If fred03.dat has below content, we want to rename then author, change the time to current, and remove the phone number from file.
 
Promram name: granite
Author: Gilbert Bates
Company: RockSoft
Department: R&D
Phone: +1 503 555-0095
Date: Tues March 9, 2004
Version: 2.1
Size: 21k
Status: Final beta
 
#!/usr/bin/perl
# chomp(my $date=`date`);
my $date=localtime;
$^I=".bak";
while(<>){
 s/^Author:.*/Author: Randal L. Scharwartz/;
 s/^Phone:.*//s;
 s/^Date:.*/Date: $date/;
 print;
}
 
Shell command `date` and perl function 'localtime' has similar output.
 
$^I set the backup file name: when we set it as ".bak", the while(<>) will backup fred03.dat to fred03.dat.bak, then update lines using the block s///, print it to a new copy of fred03.dat.
 
If we set $^I='' , it will modify the original file but do not backup.
 
We can do the modification in command line.
perl -p -i.bak -w -e 's/Randall/Randal/g' fred03.dat
 
-p  print;
-i  set $^I;
-w  set warnings;
-e  execute perl code.
 
The command line above is the same as below program:
 
#!/usr/bin/perl -w
$^I=".bak";
while(<>){
 s/Randall/Randal/g;
 print;
}
 
Exercises:
 
1. Write a patten to make it matches 3 continued $what, if $what is fred|barney, it matches fredfredfred and fredbarneyfred and so on.
 
#!/usr/bin/perl
my $what="fred|barney";
my $whats="($what)" x 3;
while(<>){
 if(/$whats/){
  print;
 }
}
###################################
 
2. Write a program, read from input file and change all Fred (case insensitive) to Larrly. Get input file from command line, make the changes into out file named input file with .out ended.
 
#!/usr/bin/perl
$file_in=$ARGV[0];
$file_out=$file_in . ".out";
open IN, "< $file_in"
 or die "Can't open $file_in:$!\n";
open OUT, "> $file_out"
 or die "Can't create $file_out: $!\n";
while(<IN>){
 s/fred/Larry/gi;
 print OUT;
}
###################################
 
3. Modify last program, repace all Fred with Wilma meanwhile replace all Wilma to Fred, both case insensitive.
 
#!/usr/bin/perl
$file_in=$ARGV[0];
$file_out=$file_in . ".out";
open IN, "< $file_in"
 or die "Can't open $file_in:$!\n";
open OUT, "> $file_out"
 or die "Can't create $file_out: $!\n";
while(<IN>){
 chomp;
 s/fred/\n/gi;
 s/wilma/Fred/gi;
 s/\n/Wilma/gi;
 print OUT;
}
###################################
 
4. Write a program to add a line to all your program, the line should be after line #!PERL-PATH.
The line content is: ## Copyright (C) 2012 by Yours Truly
Make a backup and modify the "source" file.
 
#!/usr/bin/perl
$^I=".bak";
while(<>){
 s|^#!.*?\n|$&## Copyright (C) 2012 by Yours Truly\n|;
 print;
}
###################################
 
5. Modify last program, if one program already has "Copyright" statement then don't modify that.
 
#!/usr/bin/perl
my %do_these;
foreach(@ARGV){
 $do_these{$_}=1;
}
 
while(<>){
 if(/^## Copyright/){
  delete $do_these{$ARGV};
 }
}
 
@ARGV=sort keys %do_these;
$^I=".bak";
while(<>){
 s|^#!.*?\n|$&## Copyright (C) 2012 by Yours Truly\n|;
 print;
}
###################################