In che modo ls -l formatta il suo output in modo così ordinato?


19

In che modo ls -lformatta il suo output in modo che i contenuti delle colonne si allineino correttamente?

terminale

Risposte:


34

Il codice sorgente di lsè disponibile per la navigazione online su GNU Savannah . Nella maggior parte dei casi, viene calcolata la larghezza massima richiesta (ad esempio, utilizzando la mbswidthfunzione per il testo), quindi utilizza i classici identificatori del printfformato della funzione C e alcune imbottiture manuali. Vedi, ad esempio, le funzioni format_user_or_group()e gobble_file().

TL; DR: non c'è "magia", solo un sacco di calcolo grugnito.


Se vuoi tabelle così pulite per il tuo output, usa 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

4
Dato che hai usato / etc / fstab come esempio, non posso fare a meno di suggerire findmnt --fstab. Il pacchetto util-linux include anche una libreria "libsmartcols" (precedentemente libtt) che usa in findmnt, lsblk, ecc. Per stampare una tabella allineata.
Grawity

@grawity nice. Avevo usato findmntprima, ma non avevo mai capito che potesse fare anche questo.
Muru,

Buono anche a sapersi: su Ubuntu / debian /bin/lsfa parte del pacchetto (GNU) coreutils. Puoi trovarlo eseguendo dpkg-query -S /bin/ls. Una volta che conosci il nome del pacchetto, puoi scaricare qualsiasi codice sorgente esatto del pacchetto Ubuntu da cui è stato creato il binario (questo è importante) usandoapt-get source <package_name>
arielf

17

Oltre alla risposta di @muru , ecco la parte del codice sorgente che calcola la widthgiusta giustificazione dell'output. :

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;
}

Esso utilizza, printf ("%*lu ", width, id);. NOTA: identificatore di larghezza di campo variabile '*'

In questo caso, non è possibile prevedere la larghezza del campo necessaria per l' ls -lesecuzione, ovvero i nomi delle directory possono variare in lunghezza. Ciò implica che la larghezza del campo stesso deve essere una variabile , per la quale il programma calcolerà un valore .

C utilizza un asterisco nella posizione dell'identificatore della larghezza del campo per indicare a printf che troverà la variabile che contiene il valore della larghezza del campo come parametro aggiuntivo.

Ad esempio, supponiamo che il valore corrente di width sia 5. L'istruzione:

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

stamperà: (notare la spaziatura)

   10   11

Il widthEcco scontext_width, calcolato gooble_file, l' altro la funzione che ho citato.
Muru,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.