Bash

我只需要在目錄中查找目錄,但不包括連結目錄及其連結

  • November 18, 2018

我在根目錄中,裡面有一些文件夾:

0.1
0.2
0.3
0.4
0.5
0.6
shortcut -> 0.6

我需要列出沒有快捷方式以及 0.6 文件夾的上述目錄。我不會在此位置上方或任何這些文件夾中搜尋。我這裡可能也有一些文件,但我需要忽略它們。具有相同命名約定的新文件夾將不時添加到此目錄中,因此此搜尋將包含在 bash 腳本中,並且在添加新文件夾和執行腳本時將生成不同的結果。

我試過find -P . -maxdepth 1 -type d -ls但沒有運氣。

除了找到符號連結並跟踪它們之外,沒有辦法知道符號連結的目標名稱是什麼。

因此我們可以這樣做(假設bash版本 4.0 或更高版本):

#!/bin/bash

# Our blacklist and whitelist associative arrays (whitelist is a misnomer, I know)
# blacklist: keyed on confirmed targets of symbolic links
# whitelist: keyed on filenames that are not symbolic links
#            nor (yet) confirmed targets of symbolic links

declare -A blacklist whitelist

for name in *; do
   if [ -L "$name" ]; then

       # this is a symbolic link, get its target, add it to blacklist
       target=$(readlink "$name")
       blacklist[$target]=1

       # flag target of link in whitelist if it's there
       whitelist[$target]=0

   elif [ -z "${blacklist[$name]}" ]; then
       # This is not a symbolic link, and it's not in the blacklist,
       # add it to the whitelist.
       whitelist[$name]=1
   fi
done

# whitelist now has keys that are filenames that are not symbolic
# links. If a value is zero, it's on the blacklist as a target of a
# symbolic link.  Print the keys that are associated with non-zeros.
for name in "${!whitelist[@]}"; do
   if [ "${whitelist[$name]}" -ne 0 ]; then
       printf '%s\n' "$name"
   fi
done

該腳本應該以您的目錄作為目前工作目錄執行,並且不假設該目錄中的名稱。

如果您的意思是您想要不是符號連結目標的目錄類型的所有文件,請使用:shortcut``zsh

#! /bin/zsh -
printf '%s\n' *(/^e'{[[ $REPLY -ef shortcut ]]}')
  • (...): glob 限定符,用於根據其他條件進一步過濾文件,而不僅僅是名稱
  • /: 只有目錄類型的文件
  • ^: 否定以下 glob 限定符
  • e'{shell code}':根據評估的結果(退出狀態)選擇文件shell code(正在考慮的文件所在的位置$REPLY
  • [[ x -ef y ]]``x: 如果並且y指向同一個文件(在符號連結解析之後),則返回 true 。通常,它通過比較兩個文件的設備和 inode 編號(通過stat()解析符號連結的系統呼叫獲得)來實現。

使用 GNU find(列表未排序,文件名以 為前綴./):

#! /bin/sh -
find -L . ! -name . -prune -xtype d ! -samefile shortcut
  • -L:對於符號連結,考慮符號連結的目標。-samefile這是做與上述相同的事情所必需zsh-ef
  • ! -name . -prune: 修剪除.. 相同 -mindepth 1 -maxdepth 1但更短和標準。
  • -xtype d:現在-L,我們需要-xtype在符號連結解析之前匹配原始文件的類型:
  • -samefile shortcut:如果文件與shortcut(在符號連結解析後-L)相同,則為 true

列出除目前目錄中任何符號連結的目標之外的所有目錄:

#! /bin/zsh -
zmodload zsh/stat
typeset -A ignore
for f (*(N@-/)) {
  zstat -H s -- $f &&
    ignore[$s[device]:$s[inode]]=1
}

printf '%s\n' *(/^e'{zstat -H s -- $REPLY && ((ignore[$s[device]:$s[inode]]))}')

請注意,zsh-bases 忽略隱藏文件。添加Dglob 限定符或設置dotglob選項以考慮它們。

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