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

Hello Monks, I have a quick question. I am using
@GetServiceList = `grep ^[a-z] ./sub/100087.txt`; chomp @GetServiceList; print join (", ", @GetServiceList);
in order to print a list of services displayed in a text file. The text file contains text on each line, for example...
spray sendmail crond
Currently, when I print the array, it prints:
spray, sendmail, crond
This is fine, unless the text file contains a large number of elements, in which it will cut off part of the element that touches the edge of the terminal. How would I limit the elements per line to be printed at say...7? I can't seem to find a straight forward answer to this despite lots of Google searching. Thanks in advance.

Replies are listed 'Best First'.
Re: print join n times on a line
by BrowserUk (Patriarch) on Apr 11, 2011 at 22:39 UTC

    Typically for Perl, there are several ways of doing that. Here's one:

    @a = 'a'..'z';; $s = join ',', @a;; $s =~ s[(,[^,]+){6}\K,][\n]g;; print $s;; a,b,c,d,e,f,g h,i,j,k,l,m,n o,p,q,r,s,t,u v,w,x,y,z

    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".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      The format of the substitution command is one I haven't seen before. Is s[xx][yy] equivalent to s/xx/yy/?
      Also, it does not work as written. I am using Perl 5.8.8.

      Update: fixed tags to show square brackets
        Is s[xx][yy] equivalent to s/xx/yy/?
        Yes. From perlop:
        Any non-whitespace delimiter may replace the slashes.
        Also, it does not work as written. I am using Perl 5.8.8.
        The \K requires perl 5.10 or higher (perl5100delta).
        Is sxxyy equivalent to s/xx/yy/?

        Yes. You can also use s<xx><yy> & s{xx}{yy] & s(xx)(yy) & any combination thereof.

        it does not work as written. I am using Perl 5.8.8.

        I think \K is a 5.10+ism. It was released 3 1/2 years ago and has many very useful additions, especially where regex are concerned. You should seriously consider upgrading.

        As a poor substitute, you could use this for 5.8:

        @a = 'a'..'u';; $s = join ',', @a;; $s =~ s[((?:,[^,]+){6}),][$1\n]g;; print $s;; a,b,c,d,e,f,g h,i,j,k,l,m,n o,p,q,r,s,t,u

        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".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: print join n times on a line
by toolic (Bishop) on Apr 11, 2011 at 22:51 UTC
    Another way is to use List::MoreUtils::natatime.
    use warnings; use strict; use List::MoreUtils qw(natatime); my @nums = 1 .. 30; my $it = natatime(7, @nums); while (my @vals = $it->()) { print join(',', @vals), "\n"; } __END__ 1,2,3,4,5,6,7 8,9,10,11,12,13,14 15,16,17,18,19,20,21 22,23,24,25,26,27,28 29,30
Re: print join n times on a line
by GrandFather (Saint) on Apr 11, 2011 at 23:40 UTC

    splice is the thing to use for chopping up arrays into bits. Note that the following code leaves @GetServiceList empty by the tiime it's finished so make a copy first if you need it for further processing.

    #!/usr/bin/perl use strict; use warnings; my @GetServiceList = 'a' .. 'z'; print join (', ', splice @GetServiceList, 0, 7), "\n" while @GetServic +eList;

    Prints:

    a, b, c, d, e, f, g h, i, j, k, l, m, n o, p, q, r, s, t, u v, w, x, y, z
    True laziness is hard work
Re: print join n times on a line
by ikegami (Patriarch) on Apr 11, 2011 at 22:57 UTC
Re: print join n times on a line
by ambrus (Abbot) on Apr 12, 2011 at 08:56 UTC
    open STDOUT, "|fold -sw60" or die; before you print the line to break the output to lines at most 60 characters long.
Re: print join n times on a line
by jwkrahn (Abbot) on Apr 11, 2011 at 23:18 UTC

    Another way to do it:

    open my $FH, '<', './sub/100087.txt' or die "Cannot open './sub/100087 +.txt' because: $!"; my $count = 1; while ( <$FH> ) { next unless /^[a-z]/; chomp; print; print $count++ % 7 && !eof( $FH ) ? ", " : "\n"; }
Re: print join n times on a line
by JavaFan (Canon) on Apr 12, 2011 at 13:01 UTC
    local $, = ", "; local $\ = "\n"; while (@GetServiceList >= 7) { print splice @GetServiceList, 0, 7; } print @GetServiceList if @GetServiceList;

      Correct, but let me note that there's no need for two print statements: this can be simplified to just the following.

      local $, = ", "; local $\ = "\n"; while (@GetServiceList) { print splice @GetServiceList, 0, 7; }
        Yeah, but then you have to remember when you can be out of bounds with splice/substr, and when it gives a warning or an error. I can never remember ;-)