Respuestas:
El código fuente de ls
está 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 mbswidth
función para texto), y luego usa los printf
especificadores 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
findmnt
antes, pero nunca me di cuenta de que podría hacer esto también.
/bin/ls
es parte del paquete (GNU) coreutils
. Puedes encontrar esto corriendo dpkg-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>
Además de la respuesta de @muru , aquí está la parte del código fuente que calcula width
la 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 -l
se 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
width
aquí 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.