For Programmers: Free Programming Magazines  


Home > Archive > PERL Beginners > January 2006 > Add comment to a pattern matched file line









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Add comment to a pattern matched file line
Vincent Li

2006-01-10, 9:56 pm

Hi List:

I have two files like this:

file1:
score CN_SUBJ_PROMOTE 3.100 # [0.000..3.100]
score CN_SUBJ_PROMOTION 3.600 # [0.000..3.600]
score CN_SUBJ_PROVIDE 3.000 # [0.000..3.000]

file2:
CN_SUBJ_PROMOTE
CN_SUBJ_PROMOTION

If string CN_SUBJ_PROMOTE exist in file2 and file1, add comment (#) to
file1 like:

#score CN_SUBJ_PROMOTE 3.100 # [0.000..3.100]
#score CN_SUBJ_PROMOTION 3.600 #[0.000..3.600]

I came up with this script:

#!/usr/bin/perl
use strict;
use warnings;
use Tie::File;

tie my @array1, ,'Tie::File', "file1" or die "Could not tie file1!";
tie my @array2, ,'Tie::File', "file2" or die "Could not tie file2!";

for (@array2) {
my $string = $_;
for (@array1) {
if (/$string/) {
s/$_/#$_/;
}
}
}

It did not work as I wish, any thoughts or other method to do this?

Thanks in Advance!

John Doe

2006-01-10, 9:56 pm

Vincent Li am Dienstag, 10. Januar 2006 19.59:
> Hi List:


Hi Vincent

> I have two files like this:
>
> file1:
> score CN_SUBJ_PROMOTE 3.100 # [0.000..3.100]
> score CN_SUBJ_PROMOTION 3.600 # [0.000..3.600]
> score CN_SUBJ_PROVIDE 3.000 # [0.000..3.000]
>
> file2:
> CN_SUBJ_PROMOTE
> CN_SUBJ_PROMOTION
>
> If string CN_SUBJ_PROMOTE exist in file2 and file1, add comment (#) to
> file1 like:
>
> #score CN_SUBJ_PROMOTE 3.100 # [0.000..3.100]
> #score CN_SUBJ_PROMOTION 3.600 #[0.000..3.600]
>
> I came up with this script:


Which is not easy to test, so I didn't :-)

> #!/usr/bin/perl
> use strict;
> use warnings;


Great two lines!

> use Tie::File;
>
> tie my @array1, ,'Tie::File', "file1" or die "Could not tie file1!";
> tie my @array2, ,'Tie::File', "file2" or die "Could not tie file2!";
>
> for (@array2) {
> my $string = $_;


shorter: for my $string (@array2) {

> for (@array1) {
> if (/$string/) {
> s/$_/#$_/;


Eventually it is faster just to handle the beginning of the line
with s/^./#./

> }
> }
> }
>
> It did not work as I wish, any thoughts or other method to do this?


How did it not work as expected?

You pass through the whole @array1 for every value in @array2, this is much
work. If the lines in file1 are unique and not very numerous, you could use a
hash (line_content=>line_number) instead of @array1, modify it and write it
back to file at the end. In this case, a substitution would not be necessary,
'#' could simply be prepended (i _think_ this is faster than a subst).

There may also be a useful module on search.cpan.org.

hth,
joe
Dr.Ruud

2006-01-10, 9:56 pm

John Doe:
> Vincent Li:


>
> Eventually it is faster just to handle the beginning of the line
> with s/^./#./


ITYM: s/^/#/

--
Affijn, Ruud

"Gewoon is een tijger."

John W. Krahn

2006-01-21, 7:55 am

Vincent Li wrote:
> Hi List:


Hello,

> I have two files like this:
>
> file1:
> score CN_SUBJ_PROMOTE 3.100 # [0.000..3.100]
> score CN_SUBJ_PROMOTION 3.600 # [0.000..3.600]
> score CN_SUBJ_PROVIDE 3.000 # [0.000..3.000]
>
> file2:
> CN_SUBJ_PROMOTE
> CN_SUBJ_PROMOTION
>
> If string CN_SUBJ_PROMOTE exist in file2 and file1, add comment (#) to
> file1 like:
>
> #score CN_SUBJ_PROMOTE 3.100 # [0.000..3.100]
> #score CN_SUBJ_PROMOTION 3.600 #[0.000..3.600]
>
> I came up with this script:
>
> #!/usr/bin/perl
> use strict;
> use warnings;
> use Tie::File;
>
> tie my @array1, ,'Tie::File', "file1" or die "Could not tie file1!";
> tie my @array2, ,'Tie::File', "file2" or die "Could not tie file2!";

^^^
You have an extra comma there. You should include the $! variable in the
error message so you know why it failed.


> for (@array2) {
> my $string = $_;
> for (@array1) {
> if (/$string/) {
> s/$_/#$_/;
> }
> }
> }
>
> It did not work as I wish, any thoughts or other method to do this?


You are using the string 'score CN_SUBJ_PROMOTE 3.100 #
[0.000..3.100]' as a regular expression but the regular expression will never
match the string. For example the character class [0.000..3.100] will not
match the string '[0.000..3.100]' because there are no '[' and ']' characters
in the character class. You probably want something like:

for my $string ( @array1 ) {
for my $pattern ( @array2 ) {
if ( /\b\Q$pattern\E\b/ ) {
$string = "#$string";
}
}
}



John
--
use Perl;
program
fulfillment
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com