0
#!/usr/bin/perl                                                                                                                                                                  

use strict;
use warnings;

my $directory = shift @ARGV or die "Please specify a directory";

if(opendir(DIR , $directory))

{
    my @files = readdir(DIR);

    @files = grep(/\.out/ , @files);

    closedir(DIR);

    foreach my $file (@files)
    {
        if ( -z $directory.$file )
        {
            next;
        }
        ProcessData($directory.$file);
    }

}
else
{
    print STDERR "unable to open current directory\n";
}

sub ProcessData
{
    my ($file) = @_;

    if(open(FILE , $file))
    {
        my @lines = <FILE>;
        my $lines =~ s/\,//g;
        my @fields = split(/\s+/,$lines[1]);

        print "$fields[1] $fields[2] $fields[3] $fields[4] $fields[5]\n";

        close FILE;
    }

    else
    {
        print STDERR "Can't open $file\n";
    }

I'm trying to split the second line of a set of files on white space, remove all commas, and then print some of the fields. The correct fields are printed but the comma remains, and I am given the error message: Use of uninitialized value $lines in substitution (s///). I am fairly new to Perl and quite confused by this. Any help would be hugely appreciated. Thanks in advance.

  • Can you show some example input and what you expect the output to be? There are probably a couple things you'll want to change. – hmatt1 Feb 22 '14 at 18:11
  • Sorry - this is from a subroutine, use strict is at the beginning of the code. The input is this Header: UniProtAC, Nat, Resnum, Mut, Prediction, Confidence AvrgALL: P06132, ARG, 332, HIS, PD, 0.62 – user3341369 Feb 22 '14 at 18:17
  • with AvrgALL being the start of the second line. Ideally the output would be P06132 ARG 332 HIS PD but currently each of these are followed by a comma when I run the script – user3341369 Feb 22 '14 at 18:18

1 Answers1

0

Ok you weren't too far off. The problem is that you wrote my $lines =~ s/\,//g; instead of $lines[1] =~ s/\,//g;.

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

my $file = "input.txt";
open my $fh, "<", $file or die "$!";

my @lines = <$fh>;
$lines[1] =~ s/\,//g; # This is the line that needed to be fixed
my @fields = split('\s+', $lines[1]);
print "$fields[1] $fields[2] $fields[3] $fields[4] $fields[5]\n";
close $fh;

Output:

$ cat input.txt
UniProtAC, Nat, Resnum, Mut, Prediction, Confidence
AvrgALL: P06132, ARG, 332, HIS, PD, 0.62
$ perl sub.pl
P06132 ARG 332 HIS PD

Another thing I want to point out is answered here: What's the best way to open and read a file in Perl?. Using the 3 argument form of open is generally better, and so is using lexical file handles.

Community
  • 1
  • 1
hmatt1
  • 4,939
  • 3
  • 30
  • 51
  • Thanks a lot for your help. I perhaps should have posted the whole script to make things clearer or in case someone else finds it useful: – user3341369 Feb 22 '14 at 18:33
  • will do - does the full code (just added) make it clearer what i was trying to do? – user3341369 Feb 22 '14 at 18:37
  • Yeah it's clear! You're trying to print the 5 fields for each file that ends with `.out` in the specified folder. I just tested it and it works as expected (with that 1 line changed). Remember to call it like `perl script.pl folder/`, you'll need the slash at the end of your folder name. – hmatt1 Feb 22 '14 at 18:45
  • If i change $lines to $lines[1] I now get: "my" variable @lines masks earlier declaration in same scope at ./processPredictorData3.pl line 38. syntax error at ./processPredictorData3.pl line 38, near "$lines[" Execution of ./processPredictorData3.pl aborted due to compilation errors. Thanks again for your help! Any ideas what the issue is? – user3341369 Feb 22 '14 at 18:45
  • Don't include the `my`, just `$lines[1] =~ s/\,//g;` – hmatt1 Feb 22 '14 at 18:47