Linux

使用 find 對齊列以實現 ls -l 樣式列表

  • November 14, 2021

我正在嘗試實現與ls -l使用find. 儘管末尾帶有完整路徑名而不是文件名。FWIW 我正在使用find (GNU findutils) 4.5.11.

我找到了-ls一個很好的標誌,但是它使列的間距遠大於ls -l,這沒有用,尤其是末尾有一個完整的路徑名,因為它很可能將結果推送到兩行並使得很難閱讀它們。例如…

$ find /example -ls
 7439    4 -rwxrwxr-x   1 example    example        1579 Oct 26  1985 /path/to/first/file/that/was/found
  530    4 -rwxrwxr-x   1 example    example         122 Oct 26  1985 /path/to/second/file/that/was/found

因此,雖然這可以完成工作,但我想做得更好。看著-printf標誌find,似乎可以實現同樣的事情。到目前為止,我有-printf '%M %u %g %p\n'哪個很棒,我可以自定義我想要的資訊並在其中添加其他資訊。但…

問題是,如何對齊列?

當使用者名和組名的長度不同時,這不會很好地工作。例如…

$ find /example -printf '%M %u %g %p\n'
-rwxr-xr-x root root /path/to/first/example/file
-rwxr-xr-x example example /path/to/second/example/file

我該如何解決這個問題?最好只使用find,但如果不可能,則可以使用管道連接到其他東西。的手冊頁find似乎沒有使用-printf.

-printfGNU中的格式說明符find採用寬度和對齊(等)限定符,就像printf()C 函式一樣,這意味著您可以將數據左對齊或右對齊,並且對於您目前的項目至關重要,為數據分配一定的寬度。

預設輸出:

$ find . -printf '%M %u %g %p\n'
drwxr-xr-x kk wheel .
-rw-r--r-- kk wheel ./.zshrc
-rw-r--r-- kk wheel ./file
drwxr-xr-x root wheel ./rootstuff
-rw-r--r-- root wheel ./rootstuff/SECRET
-rw------- kk wheel ./.viminfo

為使用者和組列指定寬度 (6)(右對齊):

$ find . -printf '%M %6u %6g %p\n'
drwxr-xr-x     kk  wheel .
-rw-r--r--     kk  wheel ./.zshrc
-rw-r--r--     kk  wheel ./file
drwxr-xr-x   root  wheel ./rootstuff
-rw-r--r--   root  wheel ./rootstuff/SECRET
-rw-------     kk  wheel ./.viminfo

相同,但左對齊:

$ find . -printf '%M %-6u %-6g %p\n'
drwxr-xr-x kk     wheel  .
-rw-r--r-- kk     wheel  ./.zshrc
-rw-r--r-- kk     wheel  ./file
drwxr-xr-x root   wheel  ./rootstuff
-rw-r--r-- root   wheel  ./rootstuff/SECRET
-rw------- kk     wheel  ./.viminfo

以字節為單位的文件大小,分配 5 位數字(零填充,因為只是顯示如何完成):

$ find . -printf '%M %-6u %-6g %05s %p\n'
drwxr-xr-x kk     wheel  00512 .
-rw-r--r-- kk     wheel  00000 ./.zshrc
-rw-r--r-- kk     wheel  00095 ./file
drwxr-xr-x root   wheel  00512 ./rootstuff
-rw-r--r-- root   wheel  00000 ./rootstuff/SECRET
-rw------- kk     wheel  00922 ./.viminfo

請注意,該ls命令可能會根據實際需要動態為其列分配寬度,而您的find -printf命令必須使用靜態寬度,除非您執行find兩次以首先計算每列所需的空間,然後再次實際格式化輸出(這這就是為什麼find -ls輸出如此寬的原因,它不使用兩遍方法,而是只為每一列提供足夠的空間,希望一切都能很好地對齊)。


當然,如果您沒有數千個文件,而您只想遞歸地列出所有內容(即,您不需要過濾或使用找到的路徑名做其他事情find),您可以使用ls

$ ls -d -l **/*
-rw-------  1 kk    wheel  922 Jul 25 23:46 .viminfo
-rw-r--r--  1 kk    wheel    0 Jul 19 23:39 .zshrc
-rw-r--r--  1 kk    wheel   95 Jul 25 23:51 file
drwxr-xr-x  2 root  wheel  512 Jul 26 00:00 rootstuff
-rw-r--r--  1 root  wheel    0 Jul 26 00:00 rootstuff/SECRET

這依賴於**可用的​​ globbing 模式,預設情況下它在zshshell 中,bash如果你使用shopt -s globstar. 它還依賴於 shell 匹配隱藏的名稱。如果您使用 設置選項,shellzsh將執行此操作,並使用.GLOB_DOTS``setopt GLOB_DOTS``bash``shopt -s dotglob

如果您的 globbing 模式擴展到一個列表太長以至於它生成“參數列表太長”錯誤,這將不起作用。

此輸出將不同於普通ls -l -R輸出,因為目錄不會單獨列出,並且它們之間有中斷。

引用自:https://unix.stackexchange.com/questions/532181