From: Thomas 'PointedEars' Lahn on
Ed Morton wrote:

> John Kelly wrote:
>> fw:~/temp# bash --version
>> GNU bash, version 3.2.39(1)-release (i486-pc-linux-gnu)
>> Copyright (C) 2007 Free Software Foundation, Inc.
>>
>> fw:~/temp# printf "%020s ta-da\n"
>> ta-da
>>
>> fw:~/temp# printf "%020d ta-da\n"
>> 00000000000000000000 ta-da
>
> Huh, interesting. You're right, of course, I should have used %d. Don't
> know why this works:
>
> $ bash --version
> GNU bash, version 3.2.39(20)-release (i686-pc-cygwin)
> Copyright (C) 2007 Free Software Foundation, Inc.
> $ printf "%020s ta-da\n"
> 00000000000000000000 ta-da
> $
>
> Maybe another cygwin-ism?

Yes, indeed.

,-<http://www.opengroup.org/onlinepubs/000095399/utilities/printf.html>
|
| The format operand shall be used as the format string described in the
| Base Definitions volume of IEEE Std 1003.1-2001, Chapter 5, File Format
| Notation with the following exceptions:
| [...]
| 10. If a character sequence in the format operand begins with a '%'
| character, but does not form a valid conversion specification, the
| behavior is unspecified.
^^^^^^^^^^^^^^^^^^^^^^^

,-<http://www.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap05.html>
|
| 0
| For d, i, o, u, x, X, e, E, f, g, and G conversion specifiers, leading
| zeros (following any indication of sign or base) shall be used to pad
| to the field width; no space padding is performed. If the '0' and '-'
| flags both appear, the '0' flag shall be ignored. For d, i, o, u, x,
| and X conversion specifiers, if a precision is specified, the '0' flag
| shall be ignored. For other conversion specifiers, the behavior is
| undefined.
^^^^^^^^^


PointedEars
From: John Kelly on
On Thu, 17 Jun 2010 14:30:50 +0000, John Kelly <jak(a)isp2dial.com> wrote:

>>Maybe another cygwin-ism?

>Must be a bug. The bash man page, discussing printf, says:

>> The format is reused as necessary to consume all of the arguments.
>> If the format requires more arguments than are supplied, the extra
>> format specifications behave as if a zero value or null string, as
>> appropriate, had been supplied.

>So in the case of %s, it will supply a null string, and any "string,"
>null or otherwise, should be padded with blanks, not zeros.


I also compared a newer bash version:

>hk:~# bash --version
>GNU bash, version 4.1.5(1)-release (i486-pc-linux-gnu)

>hk:~# printf "%020s ta-da\n"
> ta-da


And it too, pads with blanks, as expected.



--
Web mail, POP3, and SMTP
http://www.beewyz.com/freeaccounts.php

From: John Kelly on
On Thu, 17 Jun 2010 16:44:17 +0200, Thomas 'PointedEars' Lahn
<PointedEars(a)web.de> wrote:

>> Maybe another cygwin-ism?
>
>Yes, indeed.

>,-<http://www.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap05.html>
>|
>| 0
>| For d, i, o, u, x, X, e, E, f, g, and G conversion specifiers, leading
>| zeros (following any indication of sign or base) shall be used to pad
>| to the field width; no space padding is performed. If the '0' and '-'
>| flags both appear, the '0' flag shall be ignored. For d, i, o, u, x,
>| and X conversion specifiers, if a precision is specified, the '0' flag
>| shall be ignored. For other conversion specifiers, the behavior is
>| undefined.

Undefined by POSIX, not bash.

Two different versions of linux bash both pad strings with blanks,
ignoring a 0 flag in a %s format.

That's the bash implementor's intuitive choice, and I agree with it.
When POSIX doesn't tell you what to do, use common sense.


--
Web mail, POP3, and SMTP
http://www.beewyz.com/freeaccounts.php

From: John Kelly on
On Thu, 17 Jun 2010 09:17:04 -0500, Ed Morton <mortonspam(a)gmail.com>
wrote:

>Not all shell solutions that use non-builtins are quick and dirty. Efficiency is
>sometimes important (e.g. if you're writing some code that'll get called many
>times in a loop), but usually readability, extensibility, etc. are much more
>important.

Most programmers hate reading anyone else's code, and complain it's not
well documented. As a maintenance programmer, I had to read much poorly
documented code, and patch it without breaking anything. I had to get
tough or die.

So when I write code now, I use comments at the top to explain some
important ideas, but from there on, it's all raw code. I can read it.
If no one else can, tough.


>In this case, it's hard to imagine why you'd want to loop printing N
>equals signs repeatedly with N varying by iteration (because if it didn't you'd
>execute the command once and save the result in a variable before the loop) so
>you'd be better off not worrying about efficiency for this one and just trying
>to get something concise.

Your idea of using printf is a clever way to simulate a string repeat in
bash. I never thought of that till now. Going a little further:

With the -v option to printf, and parameter expansion, we can avoid a
loop, and do it all with builtins.

printf -v ts "%20s"; ts=${ts// /=}; echo "$ts"


--
Web mail, POP3, and SMTP
http://www.beewyz.com/freeaccounts.php

From: Janis Papanagnou on
Ed Morton wrote:
> On 6/17/2010 7:41 AM, Ed Morton wrote:
>> On 6/17/2010 3:35 AM, Marc Muehlfeld wrote:
>>> Hello,
>>>
>>> how can I print n equal signs in a shell script, without using a for
>>> loop, like
>>>
>>> for i in `seq 1 20` ; do
>>> echo -n "="
>>> done
>>
>> $ printf "%020s\n" | tr '0' '='
>> ====================
>>
>> $ n=10
>> $ printf "%0""$n""s\n" | tr '0' '='
>> ==========
>>
>>> Is there a better way and just with bash build-ins?
>>
>> Don't know if printf or tr are bash built-ins. Don't know why you'd care
>> though.
>
> ...nor do I know why I thought "0" was a better char for replacement
> than " ":
>
> $ printf "%20s\n" | tr ' ' '='
> ====================
>
> $ n=10
> $ printf '%'"$n"'s\n' | tr ' ' '='
> ==========
>
> Sigh....
>
> Ed.

Ignoring the OP's wish for using only built-ins; we can as well ignore which
characters are used for padding...

n=20
printf "%*s\n" $n "" | sed s/./=/g


Janis