디렉토리 구조를 유지하면서 여러 폴더에서 심볼릭 링크를 생성하고 싶습니다. 몇 가지 답변을 읽었으며 이제 제가 생각할 수 있는 최선의 답변은 다음과 같습니다.
find /data/DIV5/SASC/e042_ctcl/input/*/Clean_data/*/*/*.fq.gz -type f -exec ln -sf \{\} . \;
이는 동일한 디렉토리에 모든 심볼릭 링크를 생성합니다. 하지만 내가 원하는 것은 find
명령과 동일한 디렉터리 구조를 갖고 , 가능하다면 입력과 동일한 구조를 사용하는 것입니다. 예를 들어:input/*/Clean_data/*/*/*.fq.gz
파일과 디렉터리가 일치하는 경우 기호 링크는 명령을 사용하여 찾은 절대 링크와 동일한 구조를 따라야 합니다 find
.
어떤 의견이라도 감사하겠습니다.
답변1
보기 흉하고 취약하지만 작업을 완료해야 합니다.
find /data/DIV5/SASC/e042_ctcl/input/*/Clean_data/*/*/*.fq.gz -type f -print0 | \
xargs -0 -n 1 \
sh -c 'mkdir -p "$PWD/`dirname $0`"; ln -s "$0" "$PWD/`dirname $0`"'
에서 영감을 받다카오스 답변, 나는 이 대안을 생각해 냈는데, 그것도불필요한 디렉토리 정리:
find /data/DIV5/SASC/e042_ctcl/input/*/Clean_data/*/*/*.fq.gz -type f \
-printf 'mkdir -p "${PWD}/%h"; ln -s "%p" \\\n\t"${PWD}/%h"\n' | \
sed 's#/data/DIV5/SASC/e042_ctcl##' | \
sh -
그것은 필요한 것을 생성합니다목차그리고왜냐하면주문하다:
mkdir -p "${PWD}//data/DIV5/SASC/e042_ctcl/input/x/Clean_data/0/a"; ln -s "/data/DIV5/SASC/e042_ctcl/input/x/Clean_data/0/a/foobar.fq.gz" \
"${PWD}//data/DIV5/SASC/e042_ctcl/input/x/Clean_data/0/a"
그런 다음 원치 않는 디렉토리를 제거합니다.sed, 다음으로 이어집니다.
mkdir -p "${PWD}//input/x/Clean_data/0/a"; ln -s "/data/DIV5/SASC/e042_ctcl/input/x/Clean_data/0/a/foobar.fq.gz" \
"${PWD}//input/x/Clean_data/0/a"
이것왜냐하면명령은 같은 줄에서 시작됩니다.목차대상을 자르는 동안 소스를 그대로 유지하려면 다음 줄을 계속 진행하세요. 동일한 라인에 인쇄하거나 별도의 라인에 인쇄하려면 더 정교한 작업이 필요합니다.sed스크립트.
설명은 다음과 같습니다.문서~을 위한찾다,매개변수 -printf
:
%p
파일 이름(절대 경로 이름이 아니라 find에서 발견한 파일 이름, 즉 시작점 중 하나의 상대 경로).
%h
파일 이름의 선행 디렉터리(마지막 요소와 선행 슬래시를 제외한 모든 요소) 파일 이름에 슬래시가 포함되어 있지 않으면(예를 들어 명령줄에서 이름이 지정되었고 현재 작업 디렉터리에 있기 때문에) "%h"는 "."으로 확장됩니다. 이렇게 하면 "%h/%f"가 "/foo"로 확장되는 것을 방지할 수 있는데, 이는 놀랍고 아마도 바람직하지 않을 것입니다.
답변2
awk
명령을 생성 한 후 다음으로 파이프해야 합니다 bash
.
find /data/DIV5/SASC/e042_ctcl/input/*/Clean_data/*/*/*.fq.gz -type f | \
awk '{printf "mkdir -p `dirname %s`\nln -s %s ./%s \n", substr($0, 27), $0, substr($0, 27)}'
이렇게 하면 먼저 제어한 다음 마지막으로 파이프하는 명령 목록이 생성됩니다 bash
. 전체 명령은 다음과 같습니다.
find /data/DIV5/SASC/e042_ctcl/input/*/Clean_data/*/*/*.fq.gz -type f | \
awk '{printf "mkdir -p `dirname %s`\nln -s %s ./%s \n", substr($0, 27), $0, substr($0, 27)}' | bash
답변3
내 인상은 당신이 이와 같은 도구를 찾고 있다는 것입니다GNU 스토우.
GNU Stow는 파일 시스템의 서로 다른 디렉터리에 있는 다양한 소프트웨어 및/또는 패키지를 가져와 동일한 위치에 설치된 것처럼 보이게 만드는 심볼릭 링크 팜 관리자입니다. 예를 들어
/usr/local/bin
etc.의 파일에 대한 심볼릭 링크를 포함할 수 있으며/usr/local/stow/emacs/bin
, 마찬가지로 등/usr/local/stow/perl/bin
의 다른 하위 디렉터리도 재귀적으로 포함할 수 있습니다.../share
..../man
사용 사례와 일치하는지 확인하세요.
답변4
zsh에는 편리한 기능이 있습니다zmv
. 먼저 로드합니다( .zshrc
단일 세션 사용을 위해 명령줄에서 또는 명령줄에서 이 작업을 수행할 수 있음).
autoload -U zmv
alias zcp='zmv -C'
alias zln='zmv -L'
심볼릭 링크 포리스트를 다시 만드는 방법은 다음과 같이 간단합니다.
zln -s '/data/DIV5/SASC/e042_ctcl/(input/*/Clean_data/*/*/*.fq.gz)' '$1'
Clean_data
두 수준 깊이가 아닌 디렉터리를 재귀적으로 탐색 하려는 경우 :
zln -s '/data/DIV5/SASC/e042_ctcl/(input/*/Clean_data/**/*.fq.gz)' '$1'
한 가지 큰 제한 사항이 있습니다. 이는 필요한 하위 디렉터리를 생성하지 않는다는 것입니다. 필요 에 따라 디렉터리를 생성하기 위해 래퍼 함수를 정의하고 사용하여 ln
이를 수행합니다 .
ln_s_mkdir () {
mkdir -p -- ${(P)#}
ln -s "$@"
}
zmv -p ln_s_mkdir '/data/DIV5/SASC/e042_ctcl/(input/*/Clean_data/**/*.fq.gz)' '$1'
zsh를 사용하여 명령을 좀 더 빠르게 실행할 수 있습니다.내부 mkdir
및 ln
명령(대부분의 시스템에 있는 GNU 유틸리티보다 옵션이 적기 때문에 기본적으로 로드되지 않습니다.)
zmodload -F zsh/files b:zf_ln b:zf_mkdir
ln_s_mkdir () {
zf_mkdir -p -- ${(P)#}
zf_ln -s "$@"
}
zmv -p ln_s_mkdir '/data/DIV5/SASC/e042_ctcl/(input/*/Clean_data/**/*.fq.gz)' '$1'