El código fuente de lsestá disponible para navegar en línea en GNU Savannah . En la mayoría de los casos, se calcula el ancho máximo requerido (por ejemplo, usando la mbswidthfunción para texto), y luego usa los printfespecificadores de formato de función C clásico y algo de relleno manual. Ver, por ejemplo, las funciones format_user_or_group()y gobble_file().
TL; DR: no hay "magia", solo mucha computación gruñona.
Si desea tablas tan ordenadas para su propia salida, use 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
Además de la respuesta de @muru , aquí está la parte del código fuente que calcula widthla justificación correcta de la salida. :
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;
}
Utiliza, printf ("%*lu ", width, id);. NOTA: especificador de ancho de campo variable '*'
En este caso, no se puede predecir qué tan grande será el ancho del campo que necesitaremos cuando ls -lse ejecute, es decir, los nombres de los directorios pueden variar en longitud. Esto implica que el ancho del campo en sí mismo debe ser una variable , para lo cual el programa calculará un valor .
C usa un asterisco en la posición del especificador de ancho de campo para indicar a printf que encontrará la variable que contiene el valor del ancho de campo como parámetro adicional.
Por ejemplo, suponga que el valor actual de ancho es 5. La declaración:
printf ("%*d%*d\n", width, 10, width, 11);
imprimirá: (tenga en cuenta el espacio)
10 11
widthaquí es scontext_width, calculado por gooble_file, la otra función que mencioné.
findmnt --fstab. El paquete util-linux incluso viene con una biblioteca "libsmartcols" (anteriormente libtt) que usa en findmnt, lsblk, etc. para imprimir una tabla alineada.findmntantes, pero nunca me di cuenta de que podría hacer esto también./bin/lses parte del paquete (GNU)coreutils. Puedes encontrar esto corriendodpkg-query -S /bin/ls. Una vez que conozca el nombre del paquete, puede descargar cualquier código fuente exacto del paquete de Ubuntu a partir del cual se construye el binario (esto es importante) usandoapt-get source <package_name>