devi has asked for the wisdom of the Perl Monks concerning the following question:

Hii all
if($line =~ /^HWI.*/) { my @fields=split ":",$line; $id= $fields[5].":".$fields[6]; print $fields[5]," ",$fields[6]; <>; $id =~ s/\s+//; $hash1{$id}=$line; }else{ $hash1{$id}.= $line; }

This is the code i have used to get only 5 th and 6th fields
my input is smthg like this
HWI-1KL120:99:C0C9MACXX:6:1101:2105:2123 0 chr5 75483987 0 82M3I16M * 0 0
i want only 2105 2123 i,e 5th and 6th fields but this is printing entire line starting from 2105 2123
how to get only those fields?

Replies are listed 'Best First'.
Re: problem in splitting the line
by toolic (Bishop) on Jul 21, 2012 at 13:26 UTC
    The last semicolon is between 2105 and 2123. So split stuffs everything after the last semi into $fields[6], namely "2123 0 chr5 75483987 0 82M3I16M * 0 0". You need to do more work to get the number you want from $fields[6]:
    use warnings; use strict; while (<DATA>) { my $line = $_; if ( $line =~ /^HWI/ ) { my @fields = split /:/, $line; my ($f6) = $fields[6] =~ /(\S+)/; print $fields[5], " ", $f6; } } print "\n"; =for output 2105 2123 =cut __DATA__ HWI-1KL120:99:C0C9MACXX:6:1101:2105:2123 0 chr5 75483987 0 82M3I16M * +0 0
Re: problem in splitting the line
by 2teez (Vicar) on Jul 21, 2012 at 17:43 UTC
    Hi,

    If your input is a fixed field record, then unpack function could really make you smile :-) like so:

    #!/usr/bin/perl use warnings; use strict; my $str = 'HWI-1KL120:99:C0C9MACXX:6:1101:2105:2123 0 chr5 75483987 0 82M3I16M + * 0 0'; my ( $fifth, $sixth ) = unpack "x31A4xA4", $str; print $fifth, ":", $sixth, $/; # prints 2105:2123 #or even better my ($str_wanted) = unpack "x31A9", $str; print $str_wanted, $/; # prints 2105:2123
Re: problem in splitting the line
by aitap (Curate) on Jul 21, 2012 at 13:35 UTC
    my ($a,$b) = (split /\s|:/,$line)[5,6];
    EDIT: $id=join ":",(split /\s|:/,$line)[5,6];
    Sorry if my advice was wrong.
      I liked the general idea of your solution.

      Minor quibbles:
      -don't use $a and $b - these are special Perl variables reserved for things like sorting, etc and are predefined global variables. You won't write much Perl before this gets you into trouble.
      -dealing with "space" can be tricky as say " \t" may not be so apparent. I would prefer \s+ as the split parameter (one or more space characters [ \t\f\r\n])

      #/usr/bin/perl -w use strict; my $in ='HWI-1KL120:99:C0C9MACXX:6:1101:2105:2123 0 chr5 75483987 0 82 +M3I16M * 0 0'; my ($fifth, $sixth) = (split(/\s+|:/,$in) )[5,6]; print "$fifth:$sixth\n"; #2105:2123

        Thank you for your comments!

        It looks like the most strict and short-spoken solution will be my $id = join(":",(split(/\s+|:/,$in))[5,6]);.

        Sorry if my advice was wrong.