使用 LS 命令列出目錄時的文件類型和取消引用
我正在嘗試將參數組合到
ls
命令以列出目錄內容。我基本上想要實現的是列出取消引用所有連結的目錄,但明確顯示列出的項目是一個連結。我嘗試組合--dereference
and--classify
選項,但我沒有顯示連結符號 (@
),*
因為連結針對的是執行檔。關於如何獲得這樣的結果的任何想法?我對
ls
命令以外的其他選擇持開放態度。編輯: 我實際上使用了
ls
命令中的其他選項。我目前的命令及其選項如下:ls -ogq -LB --group-directories-first --time-style=long-iso
我打算在我正在建構的應用程序中解析輸出,並且不能使用帶有箭頭 (
->
) 的預設連結輸出。目錄上的其他項目(例如文件夾和文件)也必須列出。編輯(2):
澄清一下,我正在開發一個 Java 應用程序,它使用 SSH2 API 連接到伺服器並列出目錄。清單的結果然後用於使用 jsTree jQuery 外掛填充樹。目前我上面引用的命令給了我以下輸出:
felipe@simba:/mnt/drive$ ls -ogq --group-directories-first --time-style=long-iso total 12 drwxr-sr-x 2 4096 2014-06-11 18:04 folder1 drwxr-sr-x 6 4096 2014-06-27 19:35 folder2 dr-Sr-s-wt 2 4096 2014-06-27 13:51 folderWithPermissions -rw-r--r-- 1 0 2014-06-30 10:42 file.txt lrwxrwxrwx 1 49 2014-06-30 11:36 linkTeste -> folder2/dir/otherfile.txt
通過應用正則表達式,我可以通過查看權限來辨識什麼是文件夾、文件或連結。但是當我有一個連結時,我只需要列對外連結接名稱,而不是
name -> destination
. 如果我使用該命令的-L
選項,則ls
僅輸對外連結接名稱並且我獲得了引用目標的權限(這是一件好事),因為該-L
選項取消引用該連結,但是這樣我就無法知道該連結實際上是關聯。felipe@simba:/mnt/drive$ ls -ogq -L --group-directories-first --time-style=long-iso total 12 drwxr-sr-x 2 4096 2014-06-11 18:04 folder1 drwxr-sr-x 6 4096 2014-06-27 19:35 folder2 dr-Sr-s-wt 2 4096 2014-06-27 13:51 folderWithPermissions -rw-r--r-- 1 0 2014-06-30 10:42 file.txt -rwxr-xr-x 1 0 2014-06-27 18:40 linkTeste
我只需要列對外連結接名稱,知道它是一個連結並知道目標是什麼(文件、文件夾或連結)。我可以處理不同類型的輸出,因為無論如何我都要應用正則表達式。
也歡迎使用
find
or的替代方案。stat
編輯以響應更新的問題
由於您只關心連結、目錄和正常文件,並且不需要處理
ls
可以辨識的其他文件類型(FIFO、套接字等),因此您可以執行類似stat
. 對於以下範例,我創建了以下測試環境:$ ls -l total 4.0K -rw-r--r-- 1 terdon terdon 0 Jun 30 23:12 a new?line -rw-r--r-- 1 terdon terdon 0 Jun 30 23:12 a space -rw-r--r-- 1 terdon terdon 0 Jun 30 23:12 a?tab drwxr-xr-x 2 terdon terdon 4.0K Jun 30 23:11 dir1 lrwxrwxrwx 1 terdon terdon 4 Jun 30 23:13 linktodir1 -> dir1 lrwxrwxrwx 1 terdon terdon 7 Jun 30 23:13 sh -> /bin/sh
如您所見,這些包括連結、執行檔的連結、帶空格的文件名、帶製表符 (
\t
) 的文件名和帶換行符 (\n
) 的文件名。這些文件中的大多數會破壞您的ls
方法,但stat
可以正確處理它們:$ stat --printf "%A\t%N\t%F\n" * -rw-r--r-- ‘a new\nline’ regular file -rw-r--r-- ‘a space’ regular file -rw-r--r-- ‘a\ttab’ regular file drwxr-xr-x ‘dir1’ directory lrwxrwxrwx ‘linktodir1’ -> ‘dir1’ symbolic link lrwxrwxrwx ‘sh’ -> ‘/bin/sh’ symbolic link
的相關部分
man stat
:–printf=格式
像 –format,但解釋反斜杠轉義,並且不輸出強制性的尾隨換行符。如果你想要換行符,請在 FORMAT 中包含 \n
%A 人類可讀形式的訪問權限
%F 文件類型
%N 引用的文件名,如果是符號連結,則取消引用
請注意,欄位由 分隔
\t
,這意味著您將能夠優雅地處理欄位中的空格(例如在文件名中)。你提到你不能處理
->
。我不完全確定為什麼,但是您可以將其刪除sed
$ stat --printf "%A\t%N\t%F\n" * | sed 's/->//' lrwxrwxrwx ‘linktodir1’ ‘dir1’ symbolic link
或用另一個字元串替換它:
$ stat --printf "%A\t%N\t%F\n" * | sed 's/->/→/' | grep linktodir lrwxrwxrwx ‘linktodir1’ → ‘dir1’ symbolic link
或者只是解析文件類型。
根據您要執行的操作,將您正在搜尋的三種文件類型中的每一種分開並分別處理可能會很有用。如果是這樣,請使用
find
1及其-printf
選項:$ find ./ -maxdepth 1 -mindepth 1 -type f -printf '%M\t%P\t%l\n' ## files $ find ./ -maxdepth 1 -mindepth 1 -type d -printf '%M\t%P\t%l\n' ## directories $ find ./ -maxdepth 1 -mindepth 1 -type l -printf '%M\t%P\t%l\n' ## links
在這種情況下,
printf
指令是%M File's permissions (in symbolic form, as for ls). This directive is supported in findutils 4.2.5 and later. %P File's name with the name of the command line argument under which it was found removed. %l Object of symbolic link (empty string if file is not a symbolic link).
您還可以將上述內容組合成一個命令(使用
find
’-o
運算符),但它允許您-printf
根據文件類型列印任意字元串。例如:$ find ./ -maxdepth 1 -mindepth 1 \( -type l -printf 'link:\t%M\t%P\t%l\n' \) \ -o \( -type d -printf 'dir:\t%M\t%P\n' \) \ -o \( -type f -printf 'file:\t%M\t%P\n' \) file: -rw-r--r-- a?tab file: -rw-r--r-- a space link: lrwxrwxrwx linktodir1 dir1 file: -rw-r--r-- a new?line dir: drwxr-xr-x dir1 link: lrwxrwxrwx sh /bin/sh
如果它的輸出未顯示在終端上,上面的命令將正確
\t
解釋。\n
但是,要正確處理帶有換行符的文件名,您在解析時需要小心(確保“行”以 開頭[file|dir|link]:
)或\0
在每次呼叫中用作行終止符printf
而不是\n
:$ find ./ -maxdepth 1 -mindepth 1 \( -type l -printf 'link:\t%M\t%P\t%l\0' \) \ -o \( -type d -printf 'dir:\t%M\t%P\0' \) \ -o \( -type f -printf 'file:\t%M\t%P\0' \)
1
-maxdepth
並且-mindepth
是 GNU 擴展,因此這種方法僅適用於 GNUfind
。以下是針對該問題的第一個不太具體的版本的解決方案發布的。我將它們留在這裡,因為它們可能對其他人有用。
- 殼牌和
readlink
for f in *; do readlink "$f" >/dev/null && echo "$(readlink -f "$f") (link)" || echo "$f"; done
範例輸出:
/etc (link) foo sample.R sample.R~
上面遍歷目前一個下的所有文件和目錄,如果
readlink
返回成功(如果$f
是連結),它將取消引用它(readlink -f
,注意這將跟隨所有連結。如果您只想要第一級,請刪除-f
)並列印目標與(link)
。如果不是,它只會列印$f
。 2. 如果這僅適合您並且不打算被解析,請使用ls -l
:$ ls -l total 512116 -rw-r--r-- 1 terdon terdon 100641 Jun 30 19:10 er lrwxrwxrwx 1 terdon terdon 5 Jun 30 19:12 etc -> /etc/ -rw-r--r-- 1 terdon terdon 524288000 Jun 30 19:10 foo -rwxr--r-- 1 terdon terdon 353 Jun 30 15:22 sample.R -rwxr--r-- 1 terdon terdon 249 Jun 30 14:51 sample.R~
這將清楚地表明與
link -> target
.