tags:

views:

68

answers:

1

hi all

the following script text.pl (described below) define to append the $insert text between $first_line and $second_line in the file - myfile.txt

While:

$first_line=A 
$second_line=B
$insert = "hello world"

for example

before test.pl running

A
B

After I run test.pl we get:

A
hello world
B

the problem: but if there line space between A line and B line then it doesn't append the "hello world" as the following , what need to change in the script in order to append the $insert param also if I have in the file space line between A to B ?

A

B

test.pl script

use strict; 
use warnings; 

# Slurp file myfile.txt into a single string 
open(FILE,"myfile.txt") || die "Can't open file: $!"; 
undef $/; 
my $file = <FILE>; 

# Set strings to find and insert 
my $first_line = "A"; 
my $second_line = "B"; 
my $insert = "hello world"; 

# Insert our text 
$file =~ s/\Q$first_line\E\n\Q$second_line\E/$first_line\n$insert\n$second_line/; 

# Write output to output.txt 
open(OUTPUT,">output.txt") || die "Can't open file: $!"; 
print OUTPUT $file; 
close(OUTPUT); 
+1  A: 

This would replace everything between Line 1 and 2 (even nothing) by insert:

...

open my $in, '<', 'myfile.txt' or die "myfile.txt: $!";
my $content = do { undef $/; <$in> };
close $in;

# Set strings to find and insert 
my $first_line = quotemeta 'A'; 
my $second_line = quotemeta 'B'; 
my $insert = 'hello world'; 

# Insert our text 
$content =~ s/(?<=$first_line) .*? (?=$second_line)/\n$insert\n/xs; 

# Write output to output.txt 
open my $out, '>', 'output.txt' or die "output.txt: $!"; 
print $out $content; 
close $out;

...

Edit/Addendum

After reading your "enhanced specification", its much clearer how to solve this. You include the Start (^) and End ($) of the lines into the regular expression. In order to keep this maintainable, I did take out the expression and made a variable of it. I tested it and it seems to work (even with '(') and stuff):

...
# modified part

# Set strings to find and insert 
my $first_line = quotemeta ')'; 
my $second_line = quotemeta 'NIC Hr_Nic ('; 

# you won't need an array here, just write the lines down
my $insert =
'haattr -add RVG StorageRVG -string
haattr -add RVG StorageDG -string
haattr -add RVG StorageHostIds -string
haattr -delete RVG Primary
haattr -delete RVG SRL
haattr -delete RVG RLinks';

my $expr = qr{ (?<=^$first_line$)
               (\s+) 
               (?=^$second_line$)
            }xms;
# Insert our text 
$content =~ s/$expr/\n$insert\n/; 
...

I created such a file:

stuff
stuff
)
NIC Hr_Nic (
stuff
stuff

and it got inserted properly.

Regards

rbo

rubber boots
hi rubbercan you advice what quotemeta mean ?
lidia
lidia, quotemeta does on string what \Q..\E does in regular expressions, is /masks/ the special chars from external input (files etc.) so that they won't contain control chars for regular expressions. If possible, don't use \Q..\E in the regex - better prepare the strings before by quotemeta.
rubber boots
can I use @array in place $insert parameter?
lidia
lidia, if you have an array '@array', you can use $array[$number] in order to use the $number'th element of the array. Can you explain in your original post what you want to do with this program (use: edit)?
rubber boots
I have problem with this script:for example if I have in myfile.txt inplace of "A" I have "AA"then its also apend the $insert text , how to solve this?
lidia
lidia
another problem: if I have inplace A the ")" char then its not workwhy its not match the ")" ?
lidia
lidia, if it refuses to work with '(', you didn't 'quotemeta' the input string. quotemeta would make a '\(' and the regular expression would work again.
rubber boots