in reply to Re^2: In place search and replace with a hash
in thread In place search and replace with a hash

print OUT "$var1_$var2\n"

The  '_' (underscore) character is a valid identifier, i.e., variable name, symbol. Therefore, the two variables you're using are  $var1_ (note trailing _), which is not defined, and  $var2, which is. Had you been using strictures as well as warnings, Perl would not have allowed this little oversight (see strict and warnings). The proper way to write this statement (if you really need the _) is
    print OUT "${var1}_$var2\n";
(Note that I've added a ; at the end; the absence of this statement terminator caused no syntactic problem in the given code, but would have eventually — trust me.)

open FH, "<infile.txt" or die $!;
open OUT, ">outfile.txt";

Update: You seem to be back-sliding. In contrast to your OPed code, this code uses global filehandles, two-parameter open, and does not check the status of the output file open. Tsk, tsk! IMHO, the OPed code used better practices.


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

Replies are listed 'Best First'.
Re^4: In place search and replace with a hash
by hkates (Novice) on Dec 28, 2014 at 04:42 UTC
    Ah, thank you! I don't know why I was trying to use "_". Totally unnecessary. Now that you have helped me to fix most of these basic problems, I am back to the original problem of replacing the hash keys with the hash values. The hash is created with:
    use strict; use warnings; open my $fh, '<', 'hash_test.txt' or die "Cant open file $!"; LINE: while (my $line = <$fh>) { my ($key, $value) = split /\s/, $line; next LINE if not $key; $hash{$key} = $value; chomp (%hash); while ( my( $key, $value ) = each %hash ) } close $fh;

    Then the hash keys are searched for (and replaced with their associated values if found) in the input file using

    open FH, "<infile.txt" or die $!; open OUT, ">outfile.txt"; while (<FH>) { if (/(\S+):(\S+).*\n/) { $var1 = "$1"; $var2 = "$2"; print OUT "$hash{$var1} $var2\n"; } elsif (/(.*)\n/) { print OUT "$1\n"; } } close FH;

    This results in the error

    Use of uninitialized value within %hash in concatenation (.) or string at test_perl.pl line 41, <FH> line 5

    UPDATE I think the problem was that I had initialized my %hash inside a while loop. I moved it up to the beginning of the program, and it worked!

      ... back to the original problem of replacing the hash keys with the hash values.

      You say you know your translation hash is being built properly, so since I'm about to turn into a pumpkin, let me leave you with the following code to think about:

      Play with it and get the substitutions right, and you can move on to the business of writing the edited file tomorrow.


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

Re^4: In place search and replace with a hash
by hkates (Novice) on Dec 28, 2014 at 21:22 UTC

    Thanks Anomalous, I see what you mean by backsliding- I had been testing the code with a single file to control for errors with the loop (and avoid being overwhelmed by error messages). Here is the updated code that works. I see other responses suggesting better ways to do this and potential problems with the hash, and I will address those as well. But at the moment, this works. Thanks for all your help!

    #!/usr/bin/perl use strict; use warnings; my %hash = (); open my $fh, '<', 'sample_name_ID_hash.txt' or die "Cant open file $!" +; LINE: while (my $line = <$fh>) { my ($key, $value) = split /\s/, $line; next LINE if not $key; $hash{$key} = $value; chomp (%hash); } close $fh; @file_array = <*.nex> or die $!; #find all the files foreach $file (@file_array) { my $prefix = $file; $prefix =~ s/\.nex//; open FH, "$file", or die $!; print "found $file with prefix $prefix\n"; open OUT, ">out$prefix.nex" or die $!; while (<FH>) { if (/^\s+\'(\S+):(\S\d+)\|\w+\|(\d)\S+\'(.*)\n/) { $var1 = "$1"; $var2 = "$2"; $var3 = "$3"; $var4 = "$4"; print OUT "'$hash{$var1}_${var2}_$var3'$var4\n"; } elsif (/(.*)\n/) { print OUT "$1\n"; } } }