Bagaimana ls-l memformat outputnya dengan sangat rapi?

19

Bagaimana cara ls -lmemformat outputnya sehingga konten kolom berbaris dengan rapi?

terminal

Keadilan untuk Monica
sumber

Jawaban:

34

Kode sumber lstersedia untuk browsing online di GNU Savannah . Dalam kebanyakan kasus, lebar maksimum yang diperlukan dihitung (misalnya, menggunakan mbswidthfungsi untuk teks), dan kemudian menggunakan penentu printfformat fungsi C klasik dan beberapa padding manual. Lihat, misalnya, fungsi format_user_or_group(), dan gobble_file().

TL; DR: tidak ada "sihir", hanya banyak perhitungan kasar.


Jika Anda ingin tabel yang rapi untuk hasil Anda sendiri, gunakan 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
muru
sumber
4
Mengingat Anda menggunakan / etc / fstab sebagai contoh, saya tidak bisa tidak menyarankan findmnt --fstab. Paket util-linux bahkan dilengkapi dengan pustaka "libsmartcols" (sebelumnya libtt) yang digunakan dalam findmnt, lsblk, dll untuk mencetak tabel yang disejajarkan.
grawity
@ senang bagus. Saya pernah menggunakan findmntsebelumnya, tetapi saya tidak pernah menyadari itu bisa melakukan ini juga.
muru
Juga baik untuk diketahui: di Ubuntu / debian /bin/lsadalah bagian dari paket (GNU) coreutils. Anda dapat menemukan ini dengan menjalankan dpkg-query -S /bin/ls. Setelah Anda tahu nama paket, Anda dapat men-download setiap paket Ubuntu kode sumber yang sebenarnya dari mana biner dibangun (ini penting) dengan menggunakanapt-get source <package_name>
arielf
17

Selain jawaban @muru , berikut adalah bagian dari kode sumber yang menghitung widthpembenaran hasil yang benar. :

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

Ini menggunakan printf ("%*lu ", width, id);,. CATATAN: penentu lebar bidang variabel '*'

Dalam hal ini, tidak dapat diprediksi seberapa besar lebar bidang yang akan kita perlukan ketika ls -ldieksekusi, yaitu, Nama direktori mungkin panjangnya bervariasi. Ini menyiratkan bahwa lebar bidang itu sendiri harus berupa variabel , di mana program akan menghitung nilai .

C menggunakan tanda bintang di posisi specifier lebar bidang untuk menunjukkan ke printf bahwa ia akan menemukan variabel yang berisi nilai lebar bidang sebagai parameter tambahan.

Misalnya, asumsikan bahwa nilai lebar saat ini adalah 5. Pernyataan:

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

akan mencetak: (perhatikan spasi)

   10   11
Severus Tux
sumber
Di widthsini scontext_width, dihitung oleh gooble_file, fungsi lain yang saya sebutkan.
muru