Как использовать printf с awk для обозначения вывода команд, разделенных столбцами

Пустые команды не допускаются, поэтому просто удалите строку else .

2
03.03.2016, 06:18
4 ответа

Вы можете заставить столбцы выстроиться в ряд, не используя команду column, полностью внутри awk, выполнив

# fcinfo hba-port | awk '
                        BEGIN{man[-1]="HBA_Manufacturer"
                              ver[-1]="Firmware_Version"
                              sta[-1]="State"
                              man[0]="----------------"
                              ver[0]="----------------"
                              sta[0]="-----"
                              i=1
                             }
                        /Manufacturer:/     {man[i]=$2}
                        /Firmware Version:/ {ver[i]=$3}
                        /State:/            {sta[i]=$2; i++}
                        END {
                             maxlen1 = maxlen2 = maxlen3 = 0
                             for (j=-1; j<i; j++) {
                                 if (length(man[j]) > maxlen1) maxlen1 = length(man[j])
                                 if (length(ver[j]) > maxlen2) maxlen2 = length(ver[j])
                                 if (length(sta[j]) > maxlen3) maxlen3 = length(sta[j])
                             }
                             for (j=-1; j<i; j++) {
                                 printf("%-*s  %-*s  %-*s\n", maxlen1, man[j],
                                                              maxlen2, ver[j],
                                                              maxlen3, sta[j])
                             }
                            }'

Это считывает весь входной текст, сохраняя данные (включая заголовки) в массивах man, ver и sta (производитель, версия и состояние).  Заголовки столбцов помещаются в записи [-1], а тире (которые образуют линию между заголовками и данными) помещаются в записи [0] ; Они становятся первыми двумя строками выходного файла (см. ниже).  Фактические данные начинаются с [1].

Когда программа доходит до конца данных, он определяет максимальную длину данных (включая заголовки) в каждом столбце, а затем печатает все данные (из массивов), используя рассчитанную ширину столбцов.

  • printf("%16s", "Emulex") печатает Emulex (десять начальных пробелов, за которыми следует имя из шести символов, всего 16 символов).
  • printf("%-16s", "Emulex") (обратите внимание на -) печатает Emulex (имя из шести символов, за которым следуют десять пробелов, всего 16 символов).
  • printf("%-*s", 16, "Emulex") делает то же самое, что и printf("%-16s", "Emulex"), только вместо строки формата она получает 16 из списка аргументов.
  • Таким образом, вышеприведенный результат будет иметь вид

    HBA_Manufacturer Firmware_Version State
    ---------------- ---------------- -----
    Emulex 2.82a4 online
    Emulex 2.82a4 online
    Emulex 2.82a4 offline
    Emulex 2.82a4 offline
    Emulex 2.82a4 online
    Emulex 2.82a4 online
    

    Если вам нужно больше пространства между колонками, добавьте пробелы в формат printf.  Например, "%-*s %-*s %-*s\n" даст вам что-то близкое к показанному примеру вывода.

  • В приведенном вами примере после заголовков идет сплошной ряд тире. после заголовков.  Моя команда, как показано выше, даст только короткий ряд тире под каждым заголовком.  Это становится еще более очевидным, если некоторые из ваших данных длиннее:

    HBA_Manufacturer Firmware_Version State
    ---------------- ---------------- -----
    Emulex 2.82a4 онлайн
    Emulex 2.82a4 online
    Какой-то_другой_производитель 2.82a4 offline
    Emulex 2.82a4 offline
    Emulex 2.82a4 online
    Emulex 2.82a4 online
    

    Это может быть исправлено, если необходимо.

  • Это может не сработать, если ваши входные данные огромны, потому что awk может не хватить места для хранения всех данных.
  • Это может завершиться с синтаксической ошибкой. если у вас старая версия awk (например, на Solaris).  Если это произойдет, попробуйте поместить оператор printf в одну строку, как например
       printf("%-*s %-*s %-*s\n", maxlen1, man[j], maxlen2, ver[j], maxlen3, sta[j])
4
27.01.2020, 21:52

Если ширина, которую вы хотите для каждого столбца, заранее определена, awk имеет printf , который работает так же, как в C ; здесь, если вы хотите, например, столбцы из 20, 15 и 10 символов с 2 пробелами между:

(as in Q)  /State/{printf "%-20s  %-15s  %-10s\n", m, F, $2}

( - выровнены по левому краю; по умолчанию выровнены по правому краю, обычно хорошо для чисел но не текст.)

Если вы хотите, чтобы ширина соответствовала данным, вы МОЖЕТЕ сохранить данные в массивах, вычислить желаемую ширину, а затем использовать эту ширину со звездочкой, например printf "% - * s" , len, data - но , поскольку G-Man ответил на столбец , программа делает это проще.

2
27.01.2020, 21:52

Вы можете заставить столбцы выстроиться в линию, выполнив

# fcinfo hba-port | awk '
                        BEGIN {printf("HBA_Manufacturer Firmware_Version State\n")
                               printf("---------------- ---------------- -----\n")
                              }
                        /Manufacturer:/ {m=$2}
                        /Firmware Version:/ {F=$3}
                        /State/ {print m, F, $2}' | column -t

Это даст результат, подобный

HBA_Manufacturer  Firmware_Version  State
----------------  ----------------  -----
Emulex            2.82a4            online
Emulex            2.82a4            online
Emulex            2.82a4            offline
Emulex            2.82a4            offline
Emulex            2.82a4            online
Emulex            2.82a4            online

Примечания:

  • Если вам нужно больше пространства между столбцами, используйте опцию --output-separator string (или -o string) в конце, чтобы указать строку, которую нужно поместить между колонками. По умолчанию используется два пробела; например, ...| column -t -o " " (с четырьмя пробелами) даст вам что-то более близкое к тому. к показанному вами примеру.
  • В показанном вами примере после заголовков идет непрерывный ряд тире после заголовков.  Моя команда, как показано выше, даст только короткий ряд тире под каждым заголовком.  Это становится еще более очевидным, если некоторые из ваших данных длиннее:

    HBA_Manufacturer Firmware_Version State
    ---------------- ---------------- -----
    Emulex 2.82a4 онлайн
    Emulex 2.82a4 online
    Какой-то_другой_производитель 2.82a4 offline
    Emulex 2.82a4 offline
    Emulex 2.82a4 online
    Emulex 2.82a4 online
    

    Это можно исправить, если необходимо.

1
27.01.2020, 21:52

вам, возможно, придется настроить вкладки методом проб и ошибок, но примерно -

awk 'BEGIN{printf("HBA_Manufacturer\t\t\tFirmware_Version\t\t\tState\n----------------------------------------\n")} {... printf("%s\t\t\t%s\t\t\t%s\n", m, f,$2) }
0
27.01.2020, 21:52

Теги

Похожие вопросы