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

Hi All,

I have a txt file which contains list of ports for ex: ex.txt file has the content as

[15:0]abc [31:0]def ghi jkl [3:0]mno [61:0]pqr stu etc ------
i want in the ouput as where ever bus is there like 15:0abc, it has to split and print as below:-
abc[0] abc[1] abc[2] .......... abc[15] def[0] def[1] .......... def[31] ghi jkl .......

Replies are listed 'Best First'.
Re: splitting the bus and print
by 1nickt (Canon) on Apr 19, 2016 at 12:12 UTC

    Hello perl_vams,

    Some tips for getting better answers sooner:

    1. Place your code, input data and expected output data inside <code></code> tags. It's impossible to see what your text file contains as your post now is formatted.
    2. State what you've tried, and how it fails for you. Show the code itself. You obviously already know that you need to use split as part of your solution, so show your code using split(), whether it gets the desired result or not: then you can receive useful help rather than just educated guesses.

    Hope this helps!


    The way forward always starts with a minimal test.
Re: splitting the bus and print
by AnomalousMonk (Archbishop) on Apr 19, 2016 at 16:47 UTC

    Here's some code to get you going:

    c:\@Work\Perl\monks>perl -wMstrict -le "my $s = qq{[5:0]abc\n[0:5]def\nghi\njkl\n[22:22]mno\n[6:3]pqr\nstu\n} +; print qq{<<$s>> \n}; ;; $s =~ s{ (\[ \d+ : \d+ \]) ([[:lower:]]{3}) } { make_replacement($1, $2) }xmsge; print qq{<<$s>>}; ;; sub make_replacement { my ($range_field, $string) = @_; ;; my ($hi, $lo) = $range_field =~ m{ \d+ }xmsg; return qq{$range_field$string} if $hi < $lo; ;; return join qq{\n}, map qq{$string\[$_]}, $lo .. $hi ; } " <<[5:0]abc [0:5]def ghi jkl [22:22]mno [6:3]pqr stu >> <<abc[0] abc[1] abc[2] abc[3] abc[4] abc[5] [0:5]def ghi jkl mno[22] pqr[3] pqr[4] pqr[5] pqr[6] stu >>
    Still some questions to answer:
    • Is the 'abc' string portion of '[5:0]abc' always lower case? Always exactly three digits?
    • What should happen if the "range" is inverted as in '[0:5]def'? What if it is null: '[22:22]mno'?

    Update: Added the  '[6:3]pqr' instance.


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

Re: splitting the bus and print -- oneliner
by Discipulus (Canon) on Apr 19, 2016 at 19:41 UTC
    ++ to AnomalousMonk that is exploring more and more the regex alien world (can we hope in some new tutorial: regex power tools 2016..?)

    If I understand the OP's question it this enough a oneliner:

    perl -nlE "push @res,/\[(\d+):(\d+)\](\w+)/?map{$3.qq([$_])}$2..$1:$_; +END{say for @res}" portbus.txt
    Update:
    perl -nlE "say for/\[(\d+):(\d+)\](\w+)/?map{$3.qq([$_])}$2..$1:$_" po +rtbus.txt
    L*

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
      the below two options you suggested are not working for me. I'm getting error as "Bad : modifier in $ ($).". Can u please help me on this......
      perl -nlE "say for/\[(\d+):(\d+)\](\w+)/?map{$3.qq([$_])}$2..$1:$_" po +rtbus.txt perl -nlE "push @res,/\[(\d+):(\d+)\](\w+)/?map{$3.qq([$_])}$2..$1:$_; +END{say for @res}" portbus.txt
        Bad : modifier in $ ($). seems to me not a Perl error.

        A fast search indicate a C-shell or Tcsh as responsable for that error.

        Please note also that, unfortunately, i used the " doublequote to delimit the oneliner, and this because i'm, unfortunately, on windows. Linux users must use signle quote around code '

        L*

        There are no rules, there are no thumbs..
        Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.