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

Hey Folks, I'm trying to find a way to easily pad numbers and strings with characters of your choice.

The method I'm using now is a simple sprintf command: sprintf("%03d", ++$i), which can for example be used in a loop.

Now, I stumbled upon this site where they say this can be easily done just by adding a few characters of code using the inventiveness of Perl.

I was wondering which that inventive method is. Any inputs on this?

Thanks, Iwein

Replies are listed 'Best First'.
Re: Clever Padding
by Ratazong (Monsignor) on Jan 27, 2010 at 11:29 UTC

    You might try the following code for padding numbers.

    my $fill = "y"; my $len = 8; my $val = 4040; my $str = substr (($fill x $len).$val, -$len, $len); print ("$str\n");

    HTH, Rata

      ...or a loop :

      my $str = 'barp'; $str = ">".$str until (length$str >=10); ## in case it is already more + than 10... print $str . "\n";

      Obviously the loop could check for anything, the length of the pad, the number of a particular character, the time...

      Updated code and added last bit

      Just a something something...
Re: Clever Padding
by ikegami (Patriarch) on Jan 27, 2010 at 18:36 UTC

    I was wondering which that inventive method is

    Switching to printf is far more than 4 characters.

    print("$line_num $rest\n"); printf("%03d %s\n", $line_num, $rest); 12345678901

    Maybe he's referring to string autoincrement.

    If you start with

    $ perl -e'my $i=0; while (<>) { print ++$i, " $_" }' file 1 foo 2 bar 3 baz 4 qux

    then this is just four more characters:

    1 234 $ perl -e'my $i="000"; while (<>) { print ++$i, " $_" }' file 001 foo 002 bar 003 baz 004 qux

    (Note that the trick will fail if you use $i as an number.)

    I would have started with

    $ perl -e'while (<>) { print "$. $_" }' file 1 foo 2 bar 3 baz 4 qux

    so I would have had to add far more characters than four. In fact, using printf is still shorter:

    $ perl -e'while (<>) { printf "%03d %s", $., $_ }' file 001 foo 002 bar 003 baz 004 qux

    (Avoiding -p and -l since this is suppose to be part of a larger program.)

Re: Clever Padding
by Anonymous Monk on Jan 27, 2010 at 10:51 UTC
    To do this you should only need to change one line by inserting an extra four characters.
    print ++$i, " ..."; printf "%03d ...", ++$i;
    Hmm, its an extra 5 characters, not 4, which means he probably started with printf.
Re: Clever Padding
by Marshall (Canon) on Jan 27, 2010 at 16:06 UTC
    I am curious. Standard printf() formats can pad with leading zeroes or leading spaces.
    #!/usr/bin/perl -w use strict; printf("%03d\n", 5); printf("%03d\n", 12345); __END__ Prints: 005 12345
    What kind of fixed field application do you have that would require padding with other than zero or space? Maybe you are asking how do deal with 12345 above? And the print should be '123' or '345'?

    I looked at your site reference http://www.comp.leeds.ac.uk/Perl/control.html#exercise and there is some really bogus advice there! Use chomp() to get rid of trailing LF or CR,LF, not chop()! chop() deletes the last char in the string no matter what it is! chomp() is conditional and only gets rid of trailing "new line" characters. In the case of Windows, chomp() will get rid of 2 characters (the CR and LF), on Unix only one (the LF) - in case of a simple string without any "new line" characters, nothing happens.

    Anyway, please explain your application with something other than zero or space leading pad characters. That would be unusual and I'd like to understand it.

      In the case of Windows, chomp() will get rid of 2 characters (the CR and LF)

      Ah, yet another person fooled by the misleading statements in perlport, most likely.

      chomp does not remove "\r" characters, even on Win32.

      Actually, I would never use chomp. s/\s+$// is a much better idea. Not only does it remove "\r" characters when on Win32 but it also removes them when on Unix (or elsewhere). Even better, it removes trailing whitespace. Trailing whitespace should never be "significant", so removing it before processing a line is a good general practice.

      - tye        

        My perlport says

        With default settings that function looks for a trailing "\n" character and thus trims in a portable way.

        Did it use to say something different?

Re: Clever Padding
by iweindesmedt (Initiate) on Jan 28, 2010 at 08:30 UTC

    Thanks all for the ideas!

    @Marshall: I'm not working on something specific, just playing around.

    The one thing I like about chop is that its like pop, but for scalars.

    The s/\s+$// regex which tye mentioned is pretty cool. Also, I like the ability of Perl to increment strings, as ikegami said. Bummer I didn't know that yet.

    As for the padding, I think I'll stick with my old technique, e.g.: substr(("0"x9)."64",-4). I think its pretty self-explaining.

    Thanks, Iwein