Suppose I have a file like this:
$ cat a
hello this is a sentence
and this is another one
And I want to print the first two columns with some padding in between them. As this padding may change, I can for example use 7
:
$ awk '{printf "%7-s%s\n", $1, $2}' a
hello this
and this
Or 17
:
$ awk '{printf "%17-s%s\n", $1, $2}' a
hello this
and this
Or 25
, or... you see the point: the number may vary.
Then a question popped: is it possible to assign a variable to this N
, instead of hardcoding the integer in the %N-s
format?
I tried these things without success:
$ awk '{n=7; printf "%{n}-s%s\n", $1, $2}' a
%{n}-shello
%{n}-sand
$ awk '{n=7; printf "%n-s%s\n", $1, $2}' a
%n-shello
%n-sand
Ideally I would like to know if it is possible to do this. If it is not, what would be the best workaround?
If you use *
in your format string, it gets a number from the arguments
awk '{printf "%*-s%s\n", 17, $1, $2}' file
hello this
and this
awk '{printf "%*-s%s\n", 7, $1, $2}' file
hello this
and this
As read in The GNU Awk User’s Guide #5.5.3 Modifiers for printf Formats:
The C library printf’s dynamic width and prec capability (for example,
"%*.*s") is supported. Instead of supplying explicit width and/or prec
values in the format string, they are passed in the argument list. For
example:
w = 5
p = 3
s = "abcdefg"
printf "%*.*s\n", w, p, s
is exactly equivalent to:
s = "abcdefg"
printf "%5.3s\n", s
does this count?
idea is building the "dynamic" fmt
, used for printf
.
kent$ awk '{n=7;fmt="%"n"-s%s\n"; printf fmt, $1, $2}' f
hello this
and this
Using simple string concatenation.
Here "%"
, n
and "-s%s\n"
concatenates as a single string for the format. Based on the example below, the format string produced is %7-s%s\n
.
awk -v n=7 '{ printf "%" n "-s%s\n", $1, $2}' file
awk '{ n = 7; printf "%" n "-s%s\n", $1, $2}' file
Output:
hello this
and this
you can use eval (maybe not the most beautiful with all the escape characters, but it works)
i=15
eval "awk '{printf \"%$i-s%s\\n\", \$1, \$2}' a"
output:
hello this
and this