Как ls -l так аккуратно форматирует вывод?

Как ls -l форматирует вывод, чтобы содержимое столбца выстраивалось аккуратно?

terminal

19
задан 7 June 2016 в 06:38

2 ответа

Исходный код ls доступен для просмотра онлайн на Саванна GNU . В большинстве случаев необходимая максимальная ширина вычисляется (например, с помощью эти mbswidth функция для текста), и затем использует классика C printf функциональные спецификаторы формата и некоторое ручное дополнение. Посмотрите, например, функции format_user_or_group() , и gobble_file() .

TL; DR: нет никакого "волшебства", просто большое вычисление пехотинца.

<час>

, Если Вы хотите такие аккуратные таблицы для своего собственного вывода, используйте column :

$ grep -vE '^#' /etc/fstab
UUID=cdff3742-9d03-4bc1-93e3-ae50708474f2 /               ext4    errors=remount-ro 0       1
/dev/mapper/lvmg-homelvm /home           btrfs   defaults,compress=lzo,space_cache,relatime 0       2
UUID="bb76cd0d-ae1d-4490-85da-1560c32679cd" none    swap sw 0 0
UUID="a264b1b1-cf82-40aa-ab9e-a810cfba169a" /home/muru/arch     btrfs defaults,compress=lzo,space_cache,relatime 0       2

$ grep -vE '^#' /etc/fstab | column -t
UUID=cdff3742-9d03-4bc1-93e3-ae50708474f2    /                ext4   errors=remount-ro                           0  1
/dev/mapper/lvmg-homelvm                     /home            btrfs  defaults,compress=lzo,space_cache,relatime  0  2
UUID="bb76cd0d-ae1d-4490-85da-1560c32679cd"  none             swap   sw                                          0  0
UUID="a264b1b1-cf82-40aa-ab9e-a810cfba169a"  /home/muru/arch  btrfs  defaults,compress=lzo,space_cache,relatime  0  2
34
ответ дан 7 June 2016 в 06:38

В дополнение к ответ @muru , вот часть исходный код , который вычисляет width для выравнивания по правому краю вывода.:

static void
format_user_or_group (char const *name, unsigned long int id, int width)
{
  size_t len;

  if (name)
    {
      int width_gap = width - mbswidth (name, 0);
      int pad = MAX (0, width_gap);
      fputs (name, stdout);
      len = strlen (name) + pad;

      do
        putchar (' ');
      while (pad--);
    }
  else
    {
      printf ("%*lu ", width, id);
      len = width;
    }

  dired_pos += len + 1;
}

Это использует, printf ("%*lu ", width, id);. ПРИМЕЧАНИЕ: переменный спецификатор ширины поля †*’

В этом случае, нельзя предсказать, как большой ширина поля нам будет нужно, когда ls -l будет выполнен, т.е., названия каталогов могут варьироваться по длине. Это подразумевает, что сама ширина поля должна быть переменная , для которого программа вычислит значение .

C использует звездочка в положении спецификатора ширины поля, чтобы указать к printf, что это найдет переменную, которая содержит значение ширины поля как дополнительный параметр.

, Например, предположите, что текущее значение ширины равняется 5. Оператор:

printf ("%*d%*d\n", width, 10, width, 11);

распечатает: (отметьте интервал)

   10   11
17
ответ дан 7 June 2016 в 06:38

Другие вопросы по тегам:

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