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

I'm reading in and splitting a tab-delimited .txt file:

while (<$IN>) { next if /^\s*@/; my @F = split("\t", $_);

Whilst most of the content has a fixed column number, a number of fields are interchangeable - making it more difficult to process/handle them in the usual fashion ($F2 etc.).

What is the best way to now handle this? Luckily the field i'm interested in has a specific substring in it "MD:Z:". Could anybody provide some code or suggestions? I've thought about searching @F using grep for the MD:Z: pattern, although this seems like it may be slow and i'm not then sure how I would extract out the index of the match to use the information contained further - the plan being to split the pattern and interpret the information.

Replies are listed 'Best First'.
Re: Handling variable column position
by BrowserUk (Patriarch) on Aug 19, 2016 at 12:32 UTC
    I've thought about searching @F using grep for the MD:Z: pattern, although this seems like it may be slow and i'm not then sure how I would extract out the index of the match

    See List::MoreUtils::firstidx()


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Awesome, thanks. Is there a way to do this without using a non-core module?
        Is there a way to do this without using a non-core module?

        Update: Added required ->'s per choroba's offline observation. (Many thanks!)

        You could write your own:

        sub firstidx(&@) { my $code = shift; $code->( $_[ $_ ] ) and return $_ for 0 .. $#_; }

        But it won't be as fast as the (XS) module.

        A possibly better version::

        sub firstidx(&@) { my $code = shift; $code->( local $_ = $_[ $_ ] ) and return $_ for 0 .. $#_; }

        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
        In the absence of evidence, opinion is indistinguishable from prejudice.

        The most obvious way would be a loop.

        $i = 0; until( $F[$i] =~ m/MD:Z/ || $i > $#F ) $i += 1 } if ($i <= $#F) { print "It's field $i\n" }
        But God demonstrates His own love toward us, in that while we were yet sinners, Christ died for us. Romans 5:8 (NASB)