Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

constructing strings from arithmetic

13 views
Skip to first unread message

heavytull

unread,
May 17, 2012, 7:51:11 PM5/17/12
to
I'm searching for a program that can construct strings from arithmetic.
For example I need the following string: aaaa, the program should
generate it by telling it to print a string of n consecutive a, n being
equal to 4 for this example.
The goal is to add blank characters at the beginning of some lines in a
script by respect to depth of code (imagine nested loops for example).
I'm trying to see if awk can do that.

Barry Margolin

unread,
May 17, 2012, 9:30:13 PM5/17/12
to
In article <jp42tf$fmj$1...@speranza.aioe.org>,
Perl can do it with its x operator: 'a' x $n evaluates to 'aaaa' when $n
is 4.

If you're just doing it for blank characters, you can do it with a
printf feature:

printf("%*s", n, "");

The * in place of the field width tells it to get the width from the
parameter list. So this prints a blank string in a field of n
characters.

--
Barry Margolin, bar...@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***

Mirko K.

unread,
May 17, 2012, 9:54:46 PM5/17/12
to
Not a single command, but maybe something like this:

count=4; printf "%${count}s" | tr ' ' 'a'

Janis Papanagnou

unread,
May 18, 2012, 4:58:19 AM5/18/12
to
On 18.05.2012 01:51, heavytull wrote:
In awk you can do it the same way as Barry showed for a printf command,
using either printf to print it or sprintf to create a string for further
use in any string contexts, as in

awk '{ padding=sprintf("%*s",4,""); x="BEGIN"padding"END"; print x }'

If you're working in shell and are using Kornshell you can define a
variable to be left/right adjusted and padded by blanks or zeroes using
the typeset declaration (with options -L, -R, or -Z). A separate padding
field can be defined as in

n=4
typeset -R $n field=""

and sample code like

printf ">>%s<< l=%d\n" "${field}" "${#field}"
field=${field// /a}
printf ">>%s<< l=%d\n" "${field}" "${#field}"

will output

>> << l=4
>>aaaa<< l=4

Kornshell has printf also as a builtin, so you won't have any process
creation penalty using that. (Whether the declarative approach or the
command call should be preferred depends on your application context.)

Janis

heavytull

unread,
May 18, 2012, 3:15:23 PM5/18/12
to
On Thu, 17 May 2012 23:51:11 +0000, heavytull wrote:

I forgot to mention that I'm using Bash 4.1

heavytull

unread,
May 18, 2012, 3:41:01 PM5/18/12
to
On Fri, 18 May 2012 03:54:46 +0200, Mirko K. wrote:
...
> Not a single command, but maybe something like this:
>
> count=4; printf "%${count}s" | tr ' ' 'a'

This one is interesting.

Ed Morton

unread,
May 18, 2012, 3:44:37 PM5/18/12
to
That part's easy:

$ echo foo | awk -v pad=5 '{printf "%*s\n", pad, $0 }'
foo
$ echo foo | awk -v pad=10 '{printf "%*s\n", pad, $0 }'
foo

The hard part will be how to identify when the "depth of code" changes.
You may find there's tools already out there that can help you with that.

Ed.

Posted using www.webuse.net

Chris F.A. Johnson

unread,
May 18, 2012, 3:36:39 PM5/18/12
to
A shell function (bash3+):

repeat() ## USAGE: repeat character length
{
local chr=$1 len=$2 str
printf -v str "%${len}s" "$chr"
printf "%s\n" "${str//?/$chr}"
}


--
Chris F.A. Johnson, author <http://shell.cfajohnson.com/>
===================================================================
Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress)

Barry Margolin

unread,
May 18, 2012, 3:55:53 PM5/18/12
to
In article <201205181...@webuse.net>,
"Ed Morton" <morto...@gmail.com> wrote:

> heavytull <heav...@hotmail.com> wrote:
>
> > I'm searching for a program that can construct strings from arithmetic.
> > For example I need the following string: aaaa, the program should
> > generate it by telling it to print a string of n consecutive a, n being
> > equal to 4 for this example.
> > The goal is to add blank characters at the beginning of some lines in a
> > script by respect to depth of code (imagine nested loops for example).
> > I'm trying to see if awk can do that.
> >
>
> That part's easy:
>
> $ echo foo | awk -v pad=5 '{printf "%*s\n", pad, $0 }'
> foo

You only got 2 characters of padding, not 5. You need to print the
padding separately from $0, otherwise it subtracts the length of $0 from
pad to get the amount of indentation.

> $ echo foo | awk -v pad=10 '{printf "%*s\n", pad, $0 }'
> foo
>
> The hard part will be how to identify when the "depth of code" changes.
> You may find there's tools already out there that can help you with that.
>
> Ed.
>
> Posted using www.webuse.net

Ed Morton

unread,
May 18, 2012, 4:17:09 PM5/18/12
to
Barry Margolin <bar...@alum.mit.edu> wrote:

> In article <201205181...@webuse.net>,
> "Ed Morton" <morto...@gmail.com> wrote:
>
> > heavytull <heav...@hotmail.com> wrote:
> >
> > > I'm searching for a program that can construct strings from arithmetic.
> > > For example I need the following string: aaaa, the program should
> > > generate it by telling it to print a string of n consecutive a, n being
> > > equal to 4 for this example.
> > > The goal is to add blank characters at the beginning of some lines in a
> > > script by respect to depth of code (imagine nested loops for example).
> > > I'm trying to see if awk can do that.
> > >
> >
> > That part's easy:
> >
> > $ echo foo | awk -v pad=5 '{printf "%*s\n", pad, $0 }'
> > foo
>
> You only got 2 characters of padding, not 5. You need to print the
> padding separately from $0, otherwise it subtracts the length of $0 from
> pad to get the amount of indentation.

I got confused by the OP first asking to print 4 "a"s and then later saying
he wants to pad a line with leading blank chars. By the time I wrote that I
was actually thinking of "foo" being "". Not really sure what is desired now
- obviously it's different solutions for each.

Ed.

Posted using www.webuse.net

heavytull

unread,
May 18, 2012, 7:41:35 PM5/18/12
to
On Fri, 18 May 2012 20:17:09 +0000, Ed Morton wrote:


> I got confused by the OP first asking to print 4 "a"s and then later
> saying he wants to pad a line with leading blank chars. By the time I
> wrote that I was actually thinking of "foo" being "". Not really sure
> what is desired now - obviously it's different solutions for each.
>
> Ed.
>
> Posted using www.webuse.net
What I want is to construct strings the way I described with whatever
character. Later I gave the problem I just wanted to resolve as an
example. At the time of posting I didn't know whether constructing with
blank characters or not would make an issue.

Ed Morton

unread,
May 18, 2012, 7:48:07 PM5/18/12
to
Here's the thing - creating a string of N any-characters has quite different
solutions to creating a string of N space-characters. Also creating a string of
space-characters has different solutions to padding text with leading
space-characters. So, you'll get answers to your specific questions here but if
you post sample input and expected output then you might get a different, better
solution to your actual problem.

Ed.

Ben Bacarisse

unread,
May 19, 2012, 9:55:05 AM5/19/12
to
heavytull <heav...@hotmail.com> writes:
<snip>
> What I want is to construct strings the way I described with whatever
> character. Later I gave the problem I just wanted to resolve as an
> example. At the time of posting I didn't know whether constructing with
> blank characters or not would make an issue.

It's a little fiddly to get it right for every character (and I would
not bet that I've covered all the cases here) but I would start with:

function rep
{
REP=${2/\\/\\\\} # replace \ with \\
REP=${REP/\//\\/} # replace / with \/
printf "%*s" $1 "" | sed -e "s/ /$REP/g"
}

so you can just use (for example)

rep 10 /

By making it a function you can easily switch to some other mechanism if
you find, later, that running sed all the time is too costly.

--
Ben.

Ed Morton

unread,
May 19, 2012, 10:58:24 AM5/19/12
to
May as well just do it in awk so you don't need to fiddle with replacing
characters that are problematic for that type of sed command like backslashes
and newlines.

$ cat rep_sed
function rep
{
REP=${2/\\/\\\\} # replace \ with \\
REP=${REP/\//\\/} # replace / with \/
printf "%*s" $1 "" | sed -e "s/ /$REP/g"
}

rep "$1" "$2"
$ ./rep_sed 3 "a"
aaa$
$ ./rep_sed 3 "
"
sed: -e expression #1, char 4: unterminated `s' command

$ cat rep_awk
function rep
{
gawk -v num="$1" -v chr="$2" 'BEGIN{
printf "%s", gensub(" ",chr,"g",sprintf("%*s",num,""))
}'
}

rep "$1" "$2"
$ ./rep_awk 3 "a"
aaa$
$ ./rep_awk 3 "
"



$

Regards,

Ed.

P.S. The equivalent in a non-gawk awk would be:

function rep
{
awk -v num="$1" -v chr="$2" 'BEGIN{
str = sprintf("%*s", num, "")
gsub(" ", chr, str)
printf "%s", str
}'
}
0 new messages