Использование переменных в формате printf

Предположим, у меня есть такой файл:

$ cat a
hello this is a sentence
and this is another one

И я хочу напечатать первые два столбца с некоторыми отступами между ними. Поскольку это дополнение может измениться, я могу, например, использовать 7:

$ awk '{printf "%7-s%s\n", $1, $2}' a
hello  this
and    this

Или же 17:

$ awk '{printf "%17-s%s\n", $1, $2}' a
hello            this
and              this

Или же 25или... вы видите смысл: число может отличаться.

Тогда возник вопрос: можно ли присвоить переменную этому Nвместо жесткого кодирования целого числа в %N-s формат?

Я попробовал эти вещи без успеха:

$ 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

В идеале я хотел бы знать, возможно ли это сделать. Если это не так, что будет лучшим решением?

4 ответа

Решение

Если вы используете * в строке формата он получает число из аргументов

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

Как читается в Руководстве пользователя GNU Awk #5.5.3 Модификаторы для форматов printf:

Поддерживается динамическая ширина и предварительная возможность printf библиотеки C (например, "%*.* S"). Вместо предоставления явных значений ширины и / или значения в строке формата они передаются в списке аргументов. Например:

w = 5
p = 3
s = "abcdefg"
printf "%*.*s\n", w, p, s

в точности эквивалентно:

s = "abcdefg"
printf "%5.3s\n", s

Это считается?

идея строит "динамику" fmt, используется для printf,

kent$   awk '{n=7;fmt="%"n"-s%s\n"; printf fmt, $1, $2}' f 
hello  this
and    this

Использование простой конкатенации строк.

Вот "%", n а также "-s%s\n" объединяет в одну строку для формата. На основе приведенного ниже примера полученная строка формата %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

Выход:

hello  this
and    this

Вы можете использовать Eval (возможно, не самый красивый из всех escape-символов, но это работает)

i=15
eval "awk '{printf \"%$i-s%s\\n\", \$1, \$2}' a"

выход:

hello          this
and            this
Другие вопросы по тегам