http://qs321.pair.com?node_id=688161


in reply to problem with string substitution output

There are some unclear parts in your code, we don't know how your data looks like (so there may be any kind of problem).

You should alwyas open one file after another and do all the work in one file at once. I reorganized your code (out of the blue, don't know your data) - maybe thats a new starting point.

... my $echo = 'ECHO'; my ($dffname, $listname) = @ARGV; my $fh; # read key/val lists open $fh, '<', $dffname or die "$dffname $!"; my %lijst = map { chomp; (split /\t|\s{2,}/)[1,0] } <$fh>; close $fh; # readfile list open $fh, '<', $listname or die "$listname $!"; my @listfiles = <$fh>; chomp @listfiles; close $fh; for my $file (@listfiles) { # read original file open $fh, '<', $file or die "$file $!"; local $/; my $content = <$fh>; close $fh; # modify content while( my ($key, $val) = each %lijst ) { next unless $val == 1; $content =~ s/^$key$/$echo/gms; $content =~ s/^$key$/$echo/; # re-subsitute first (?) } # write modified file open $fh, '>', "$file.out" or die "$file.out $!"; print $fh $content } ...

Regards

mwa

Replies are listed 'Best First'.
Re^2: problem with string substitution output
by Anonymous Monk on May 23, 2008 at 16:33 UTC
    Thanks for your reply!

    This looks more like the way it needs to be, except now everything gets replaced with "ECHO"... At least it's progress ;)
    My data file (which I read into the hash) is a document frequency list, so each line has a number, a tab and a word, like this:

    1<tab>word

    The other file is just a list of filenames.
    I'm gonna toy around with it some more, but if you have any more suggestions they are very welcome.

    Matje
      Okay, I almost got it to work like this:
      use strict; use warnings; my $echo = "ECHO"; my ($dffname, $listname) = @ARGV; my $fh; my $key=undef; # read key/val lists open $fh, '<', $dffname or die "$dffname $!"; my %lijst = map { chomp; (split /\t/)[1,0] } <$fh>; close $fh; foreach $key (sort keys %lijst) { print "The value associated with key $key is $lijst{$key}\n";} # readfile list open $fh, '<', $listname or die "$listname $!"; my @listfiles = <$fh>; chomp @listfiles; close $fh; for my $file (@listfiles) { # read original file open $fh, '<', $file or die "$file $!"; local $/; my $content = <$fh>; close $fh; # modify content while( my ($key, $val) = each %lijst ) { next unless $val == 1; $content =~ s/^$key$/$echo/gms; $content =~ s/$echo/$key/; } # write modified file open $fh, '>', "$file.out" or die "$file.out $!"; print $fh $content }
      BUT... in this piece of code:
      $content =~ s/^$key$/$echo/gms; $content =~ s/$echo/$key/;
      the value of the second $key isn't the same as the value of the first $key. The goal of this piece is to first substitute every occurence of $key with $echo, and then to substitute only the first occurence of $echo with $key (thus returning it to it's original value). And that's not working. :( Matje
        Nevermind, I just solved it :)
        use strict; use warnings; my $echo = "ECHO"; my ($dffname, $listname) = @ARGV; my $fh; my $key=undef; # read key/val lists open $fh, '<', $dffname or die "$dffname $!"; my %lijst = map { chomp; (split /\t/)[1,0] } <$fh>; close $fh; foreach $key (sort keys %lijst) { print "The value associated with key $key is $lijst{$key}\n";} # readfile list open $fh, '<', $listname or die "$listname $!"; my @listfiles = <$fh>; chomp @listfiles; close $fh; for my $file (@listfiles) { # read original file open $fh, '<', $file or die "$file $!"; local $/; my $content = <$fh>; close $fh; # modify content while( my ($key, $val) = each %lijst ) { next unless $val == 1; $content =~ s/^$key$/$echo$key/gms; $content =~ s/$echo$key/$key/; $content =~ s/$echo$key/$echo/g; } # write modified file open $fh, '>', "$file.out" or die "$file.out $!"; print $fh $content; close $fh; }
        Matje