디렉토리 내의 디렉토리만 찾고 연결된 디렉토리와 해당 링크는 제외해야 합니다.

디렉토리 내의 디렉토리만 찾고 연결된 디렉토리와 해당 링크는 제외해야 합니다.

저는 루트 디렉터리에 있고 그 안에 몇 가지 폴더가 있습니다.

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운이 없었다.

답변1

심볼릭 링크를 찾아 추적하는 것 외에는 심볼릭 링크의 대상 이름이 무엇인지 알 수 있는 방법이 없습니다.

따라서 다음과 같이 할 수 있습니다( 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

스크립트는 사용자의 디렉터리를 현재 작업 디렉터리로 사용하여 실행되어야 하며 해당 디렉터리의 이름에 대해 어떠한 가정도 하지 않아야 합니다.

답변2

모든 유형의 파일을 원하신다면목차shortcut다음과 같은 심볼릭 링크의 대상이 아닙니다 zsh.

#! /bin/zsh -
printf '%s\n' *(/^e'{[[ $REPLY -ef shortcut ]]}')
  • (...):glob 한정자는 이름 이외의 기준에 따라 파일을 추가로 필터링합니다.
  • /: 이 유형의 파일만목차
  • ^: 다음 전역 한정자를 무효화합니다.
  • e'{shell code}': 평가 결과(종료 상태)에 따라 파일 shell code(고려 중인 파일이 있는 위치 $REPLY) 을 선택합니다.
  • [[ x -ef y ]]xy: 동일한 파일을 가리키는 경우 true를 반환합니다 (심볼릭 링크 확인 후). 일반적으로 두 파일의 장치 및 inode 번호(심볼릭 링크를 해결하는 시스템 호출을 통해 얻음)를 비교하여 stat()이를 수행합니다 .

GNU 사용 find(정렬되지 않은 목록, 접두사가 붙은 파일 이름 ./):

#! /bin/sh -
find -L . ! -name . -prune -xtype d ! -samefile shortcut
  • -L: 심볼릭 링크의 경우 심볼릭 링크의 대상이 고려됩니다. 이는 -samefile위와 동일한 작업을 수행하는 데 필요합니다 .zsh-ef
  • ! -name . -prune: Trim .. 동일 -mindepth 1 -maxdepth 1하지만 더 짧고 표준입니다.
  • -xtype d: 이제 심볼릭 링크를 확인하기 전에 원본 파일의 유형을 일치시켜야 -L합니다 .-xtype
  • -samefile shortcutshortcut: 파일이 다음과 동일하면 -L참 입니다(symlink를 사용하여 해석한 후).

대상 디렉터리를 제외한 모든 디렉터리 나열어느현재 디렉토리의 심볼릭 링크:

#! /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]]))}')

-bases 는 zsh숨겨진 파일을 무시합니다. Dglob 한정자를 추가 하거나 dotglob옵션을 설정하여 이를 고려하세요.

답변3

디렉터리를 제외하려면 정리 스위치를 사용해 보십시오. 그러면 질문에 대한 답이 나올 것입니다.

find . -path ./your-folder -prune -o -maxdepth 1 -type d -print

관련 정보