Відповіді:
Вихідний код ls
доступний для перегляду в Інтернеті в GNU Savannah . У більшості випадків необхідна максимальна ширина обчислюється (наприклад, використовуючи mbswidth
функцію для тексту), а потім використовує класичні printf
специфікатори формату C та деякі ручні накладки. Див., Наприклад, функції format_user_or_group()
та gobble_file()
.
TL; ДР: немає ніякої "магії", просто безліч бурхливих обчислень.
Якщо ви хочете такі акуратні таблиці для власного виводу, використовуйте 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
findmnt
, але ніколи не розумів, що це теж може зробити.
/bin/ls
є частиною пакету (GNU) coreutils
. Ви можете знайти це, запустивши dpkg-query -S /bin/ls
. Коли ви дізнаєтесь назву пакета, ви можете завантажити будь- який точний вихідний код пакета Ubuntu, з якого побудований двійковий код (це важливо), використовуючиapt-get source <package_name>
Окрім відповіді @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
width
тут scontext_width
, обчислено gooble_file
, за іншою функцією, яку я згадав.
findmnt --fstab
. Пакет util-linux навіть постачається з бібліотекою "libsmartcols" (раніше libtt), яку він використовує у findmnt, lsblk тощо для друку вирівняної таблиці.