$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
이 작업이 필요합니다 .-prune
find
find "$HOME" \( -name Data -o -name Labs \) -prune -o -exec …
Data
이는 루트 뿐만 아니라 루트라고 불리는 모든 하위 트리를 제외합니다 $HOME/Data
. $HOME/Data
예를 들어 제외만 하고 제외하려는 경우 (구현에서 지원하는 경우 ) $HOME/sub/data
를 사용할 수 있습니다 .-path
find
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