From: Thomas 'PointedEars' Lahn on 17 Jun 2010 10:44 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 17 Jun 2010 10:48 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 17 Jun 2010 11:10 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 17 Jun 2010 11:42 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 17 Jun 2010 12:04
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 |