ln -s $SOURCE/* 제외 - 찾기 포함?

ln -s $SOURCE/* 제외 - 찾기 포함?

$SOURCE의 첫 번째 노드에 있는 모든 디렉터리와 파일을 심볼릭 링크 하고 싶습니다 $HOME/Destination/. 의사코드

ln -s $SOURCE/* exceptThese $HOME/Destination/

제안

find $HOME ! -name Data -o -name Labs -exec \
   ln -s "$0" $HOME/Documents/

확실하지 않은 것 $0.


첫 번째 노드를 제외한 모든 노드를 심볼릭 링크하는 방법은 무엇입니까?

답변1

$HOME/this또는 대신 $HOME/there/that, 등에서 심볼릭 링크를 생성하려는 경우 일치 기준은 다음과 같아야 합니다.$HOME/Data/ddd$HOME/Data$HOME/somewhere/Labs

find "$HOME" ! \( -name Data -o -name Labs \) -exec …

괄호를 놓쳤습니다. 연결은 -o이보다 더 단단히 바인딩되므로 -name Data -o name Labs -exec …명령은 이름이 지정된 파일에서만 실행됩니다 Labs( 이름이 지정된 파일은 제외 Data하지만 어쨌든 이름을 지정할 수는 없음 Labs).

Data및 아래의 모든 파일을 제외하려는 경우 디렉터리를 반복적으로 탐색하는 대신 디렉터리를 완전히 건너뛰도록 지시하는 Labs이 작업이 필요합니다 .-prunefind

find "$HOME" \( -name Data -o -name Labs \) -prune -o -exec …

Data이는 루트 뿐만 아니라 루트라고 불리는 모든 하위 트리를 제외합니다 $HOME/Data. $HOME/Data예를 들어 제외만 하고 제외하려는 경우 (구현에서 지원하는 경우 ) $HOME/sub/data를 사용할 수 있습니다 .-pathfind

find "$HOME" \( -path "$HOME/Data" -o -path "$HOME/Labs" \) -prune -o -exec …

이제 -exec그 부분입니다. -exec작업 에서 {}(자체 매개변수에서)을 사용하여 find찾은 경로를 나타냅니다. 실행하려는 명령의 끝에 하나를 배치하십시오 ;(쉘에서 구문 분석되지 않고 쉘에 전달되도록 따옴표로 묶음).find

find … -exec ln -s {} "$HOME/Documents/" \;

만약 너라면오직$HOME하위 디렉터리가 아닌 바로 아래에 파일을 원하는 경우 이는 find작업에 가장 적합한 도구가 아닙니다. 재귀 순회를 위해 설계되었습니다. 대신 쉘 루프를 사용하십시오. 이 패턴은 *도트 파일, 즉 이름이 로 시작하는 모든 파일을 건너뛰고 .이 패턴은 명시적으로 건너뛰어야 하는 .*모든 도트 파일과 .및 를 일치시킵니다...

for x in ~/* ~/.*; do
  case "${x##*/}" in
    .|..|Data|Labs) continue;; # Skip those entries
  esac
  ln -s "$x" "$HOME/Documents";;
done

답변2

Bash에서는 extglob 옵션을 활성화하여 이를 수행할 수 있습니다:

$ shopt -s extglob                                #Enables extglob
$ ls -l "$HOME"/!(Data|Labs|Documents)            #Test run
$ ln -s "$HOME"/!(Data|Labs|Documents) \
        "$HOME"/Documents/                        #Create symlinks
$ shopt -s extglob                                #Disable extglob

편집: find를 사용한 원본 게시물을 기반으로 하면 다음과 같이 작동합니다.

$ find "$HOME" \
    -mindepth 1 \
    -maxdepth 1 \
    ! -name Data ! -name Labs ! -name Documents\
    -exec ln -s {} "$HOME"/Documents/ \;

mindepth옵션에는 루트 디렉터리가 포함되지 않습니다. 이 maxdepth옵션에는 하위 디렉터리가 포함되지 않습니다. 각 항목에는 ! -name경로가 제외됩니다. {}논쟁은 -exec당신이 대신 찾고 있는 것 입니다 $0.

답변3

find첫 번째 결과를 제외한 모든 결과를 연결하려면 다음을 수행하면 됩니다.

for item in "$(find "$HOME" ! -name Data -o -name Labs | tail --lines=+2)"; do
    ln -s "$item" "$HOME"/Documents/
done

관련 정보