Я понимаю, как использовать функцию printf в awk, но я не хочу указывать каждое поле.
Например, предположим, что это мой файл:
c1|c2|c3|c4|c5
c6|c7|c8|c9|c10
c11|c12|c13|c14|c15
Я хочу отформатировать его так, чтобы первое поле каждой записи было шириной c11 - самой длинной ячейки в первом поле:
c1 |c2|c3|c4|c5
c6 |c7|c8|c9|c10
c11|c12|c13|c14|c15
Я понимаю, что я мог бы указать:
awk -F"|" '{printf "%-3s%s%s%s%s\n", $1, $2, $3, $4, $5}' file > newfile
Давайте предположим, что я знаю, какой должна быть ширина первого столбца, но я НЕ знаю, сколько полей в файле. В основном я хочу сделать что-то вроде:
... '{printf "%-3s|", $1}'
... а затем распечатайте остальные поля в их исходном формате.
awk
text-formatting
printf
Кейли О'Киф
источник
источник
sed 's/|/'' '' '' |/;s/\(...\) */\1/'
(здесь добавление дополнительных кавычек для вставки этих трех пробелов, поскольку комментарии SE сжимают непрерывные пробелы в одну)Ответы:
Вы можете использовать только
sprintf
для переформатирования$1
.Ex.
источник
awk -vf1=3 'BEGIN{OFS=FS="|"}{$1=sprintf("%-*s",f1,$1)}1' test.txt
Чтобы определить наибольшую / самую длинную длину первого поля, а затем переформатировать значения в поле в соответствии с этой длиной, вам придется выполнить два отдельных прохода по файлу.
(обратите внимание, что входной файл указан дважды в командной строке)
Для данных, которые вы предоставляете, это даст
Первый проход обрабатывается
FNR == NR
блоком, который просто отслеживает самое длинное видимое поле (m
содержит максимальную видимую длину) и переходит к следующей строке.Второй проход обрабатывается последним блоком, который форматирует первое поле, используя
sprintf()
. Строка формата%-*s
означает «выровненную по левому краю строку, ширина которой задается целочисленным аргументом перед аргументом, который содержит фактическую строку».Очевидно, это можно расширить, чтобы сделать все столбцы, превратив скаляр
m
в массив, который содержит максимальную ширину каждого столбца:источник
Интеллектуальный способ - это то, что предложил стилдрайвер . Излишне запутанный способ - перебирать все поля:
Но просто
sprintf
$1
и покончим с этим.источник
В Awk вы можете использовать «*» для генерации динамической строки формата printf.
Если вы уже знаете длину, вы можете передать длину поля для первого столбца с -v.
Примечание: если вы не знали, какова длина первого столбца, вы можете сохранить значения в массиве, а затем найти максимальную длину столбца и распечатать все это в блоке END.
источник