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

Monks!!!

Why this perfect (tested in ubuntu linux) script

perl -ane '$s = ""; foreach (@F) { /(\d+)-(\d+)/ and $2 - $1 >= 30 and $s .= " $1-$2" } print "$F[0]$s\n" if $s' input.txt

is not running on windows machine?

it shows:

C:\Users\Desktop\x\New folder>perl -ane '$s = ""; Can't find string terminator "'" anywhere before EOF at -e line 1. C:\Users\Desktop\x\New folder>foreach (@F) { /(\d+)-(\d+)/ and $2 - $1 + >= 30 and $s .= " $1-$2" } 'foreach' is not recognized as an internal or external command, operable program or batch file.

I have also tried to wrapped in in one line as:

perl -ane '$s = ""; foreach (@F) { /(\d+)-(\d+)/ and $2 - $1 >= 30 and + $s .= " $1-$2" } print "$F[0]$s\n" if $s' input.txt

still this :-( :

Can't find string terminator "'" anywhere before EOF at -e line 1.

Changing ' to " wont change the error.

Some wisdom please.

Thanks

Replies are listed 'Best First'.
Re: Why this script is not running on windows?
by Corion (Patriarch) on Nov 01, 2016 at 10:24 UTC

    Please learn about the shell you're using. cmd.exe does not support multiline commands. You will need to fit the complete command on one line.

    Also, cmd.exe does not know about single quotes. You will need to change the surrounding quotes to double quotes. This also means that you will need to change all inner double quotes to qq().

    perl -ane "$s = qq(); foreach (@F) { /(\d+)-(\d+)/ and $2 - $1 >= 30 a +nd $s .= qq( $1-$2) }; print qq($F[0]$s\n) if $s" input.txt
      Perfect.. thanks Corion
Re: Why this script is not running on windows?
by haukex (Archbishop) on Nov 01, 2016 at 10:35 UTC

    Hi abhikalrt53,

    Why not turn it into a real script?

    $ perl -MO=Deparse -ane '$s = ""; foreach (@F) { /(\d+)-(\d+)/ and $2 +- $1 >= 30 and $s .= " $1-$2" } print "$F[0]$s\n" if $s' LINE: while (defined($_ = <ARGV>)) { our @F = split(' ', $_, 0); $s = ''; foreach $_ (@F) { $s .= " $1-$2" if /(\d+)-(\d+)/ and $2 - $1 >= 30; } print "$F[0]$s\n" if $s; }

    With a bit of cleanup:

    #!/usr/bin/env perl use warnings; use strict; while (<>) { my @fields = split; my $s = ''; for (@fields) { if ( /(\d+)-(\d+)/ && $2 - $1 >= 30 ) { $s .= " $1-$2"; } } print "$fields[0]$s\n" if $s; }

    Hope this helps,
    -- Hauke D

      Hey Hauke how are you?

      This code also seems fine.. I want to ask you another question as I could not find a way to do it in my one liner.

      This Script takes on a input file like:

      NP_416485.4: 970-970, 991-992, 1126-1235 NP_417679.2: 209-413, 418-421, 441-542

      and gives a output like:

      NP_416485.4: 1126-1235 NP_417679.2: 209-413 441-542

      But instead of only <space> in output, I want a output like the input format.. i.e.,comma then space:

      NP_416485.4: 1126-1235 NP_417679.2: 209-413, 441-542

      Thanks

        Hi abhikalrt53,

        One way to do this would be to store the ranges in an array, and then use join when outputting the array.

        A simpler way to do it would be to add the comma only under certain conditions, i.e. $s .= ',' if ...; - I'm not going to give away the condition because I don't think it's appropriate I do all of your (home)work for you ;-)

        Hope this helps,
        -- Hauke D