파일에 나열된 패턴과 일치하는 특정 디렉터리만 반복적으로 복사합니다.

파일에 나열된 패턴과 일치하는 특정 디렉터리만 반복적으로 복사합니다.

다음과 같은 구조의 디렉토리가 있습니다.

-- 201893208
   └── 8Z12
          └── ko_8Z12_Full
          └── wp_we_8Z12_FullDAT
          └── 8Z12_DATFull
   └── P011
          └── P011_Full
          └── 8Z12_FullDAT
          └── P011_DATFull
   └── 9FZA
          └── kl_wt-we-w_kl9-9FZA_Full
          └── ffd-9FZA_FullDAT
          └── 8fdZ12232_9FZA_DATFull
-- 903240920
   └── P0fsa
          └── P0fsa_Full
          └── P0fsa_FullDAT
          └── P0fsa_DATFull
   └── Paaaf
          └── we-Paaaf_ww_fl_Full
          └── Paaaf_FullDAT
          └── Paaaf_DATFull
   └── 9FZATYYY
          └── 9FZATYYY_Full
          └── 9FZATYYY_FullDAT
-- wt0340291
   └── OPF1121
          └── OPF1121_Full
          └── 8Z12_DATFull
   └── KLOFJ9
          └── lop_KLOFJ9_ffj_Full
          └── powt_KLOFJ9_DATFull
   └── LP02323
          └── wr_we_LP02323_Full
          └── wr_we_LP02323_FullDAT

위에 나열된 각 폴더에는 수천 개의 파일이 있습니다. 그런 다음 각각에는 많은 하위 디렉터리가 있습니다. 예를 들어 8Z12위에 나열된 세 개의 폴더뿐만 아니라 수천 개의 파일도 포함되어 있습니다.

오직_Full끝에 (가 있는 이름을 복사하고 싶습니다 .완전한 데이터목차복사하면 안 된다)그리고아래 목록의 패턴이 포함되어 있습니다.

LP02323
KLOFJ9
Paaaf
9FZA

즉, 위 목록의 문자열이 포함된 디렉터리입니다.그리고 Full해당 이름으로 복사해야 합니다(DAT는 아님).

따라서 위의 예에서는 다음 디렉터리(및 모든 내용과 하위 디렉터리)만 복사해야 합니다.

wr_we_LP02323_Full
lop_KLOFJ9_ffj_Full
we-Paaaf_ww_fl_Full
kl_wt-we-w_kl9-9FZA_Full

내가 이해한 바에 따르면 rsync정규 표현식은 지원되지 않으므로 find이 작업을 먼저 수행해야 합니다(틀렸다면 정정해 주십시오). 그러나 여러 하위 디렉터리에 깊게 묻혀 있는 경우에도 모든 디렉터리와 하위 디렉터리가 확인되고 모든 관련 폴더가 복사되었는지 어떻게 확인할 수 있습니까? (위의 예는 원래 폴더 구조의 단순화된 예입니다.)

따라서 두 가지 질문이 있습니다.

  • 패턴 목록을 에 어떻게 제공합니까 find?
  • find의 결과를 어떻게 파이프합니까 rsync?

지금까지 나는 이 경기만을 생각할 수 있다 Full:

find . -regextype sed -regex ".*/.*[^DAT]Full$"

하지만 명령에 ID 목록을 어떻게 추가합니까 find?

답변1

디렉토리 이름에 나타나야 하는 문자열 파일을 사용하여 쉘은 이러한 문자열을 반복합니다 rsync(변수의 디렉토리에서 변수 $source의 디렉토리로 복사한다고 가정 $target).

while IFS= read -r string; do
    rsync --archive --exclude='*DAT*/' --include='*/' --include="*$string*_Full/***" --exclude='*' \
        --prune-empty-dirs "$source"/ "$target"
done <strings.txt

옵션의 기능 rsync(제외/포함 패턴의 첫 번째 클릭이 중요함):

  • --archive: 소유권, 권한, 타임스탬프 등을 복사합니다.
  • --exclude='*DAT*/'DAT: 가 있는 모든 디렉터리를 제외합니다.
  • --include='*/': 모든 디렉터리를 고려합니다(이전 패턴에서 제외된 디렉터리 제외). 이는 rsync관심 있는 실제 디렉토리에 접근하는 데 필요합니다.
  • --include="*$string*_Full/***": 주어진 패턴과 일치하는 모든 디렉터리를 고려합니다.그리고이 디렉토리의 모든 것. 그렇다면 $string그게 parrot다입니다 --include="*parrot*_Full/***".
  • --exclude='*': 아직 명시적으로 포함되지 않은 것은 고려하지 마세요.
  • --prune-empty-dirs: 콘텐츠가 명시적으로 포함되지 않은 디렉터리는 전송하지 마세요.

rsync런타임 시 스키마가 어떻게 평가되는지 알고 싶다면 명령줄 -vv에 추가하세요.rsync

시험:

$ tree
.
|-- from
|   `-- a
|       `-- b
|           |-- c_A_DATFull
|           |   `-- file
|           |-- c_A_DAT_Full
|           |   `-- file
|           |-- c_A_Full
|           |   `-- file
|           |-- c_B_DATFull
|           |   `-- file
|           |-- c_B_DAT_Full
|           |   `-- file
|           |-- c_B_Full
|           |   `-- file
|           |-- c_C_DATFull
|           |   `-- file
|           |-- c_C_DAT_Full
|           |   `-- file
|           `-- c_C_Full
|               `-- file
`-- strings.txt

12 directories, 10 files

$ cat strings.txt
A
B

$ source=from
$ target=to

(여기서 루프를 실행하세요)

$ tree
.
|-- from
[...]
`-- to
    `-- a
        `-- b
            |-- c_A_Full
            |   `-- file
            `-- c_B_Full
                `-- file

17 directories, 12 files

한 번의 통화로 rsync:

set -- --exclude='*DAT*/' --include='*/'
while IFS= read -r string; do
    set -- "$@" --include="*$string*_Full/***"
done <strings.txt
set -- "$@" --exclude='*'

rsync --archive "$@" --prune-empty-dirs "$source"/ "$target"

일방 find통행:

set --
while IFS= read -r string; do
    set -- "$@" -o -name "*$string*_Full"
done <strings.txt
shift

# "$@" would now be something like
#    -name *LP02323*_Full -o -name *Paaaf*_Full -o -name ...etc

find "$source" -type d '(' "$@" ')' ! -name '*DAT*' -exec sh -c '
    source=$1; target=$2; shift 2
    for pathname do
        mkdir -p "$target/${pathname#$source}"
        rsync --archive "$pathname"/ "$target/${pathname#$source}"
    done' sh "$source" "$target" {} +

find이는 복사하려는 하위 디렉터리 목록을 생성 하는 데 사용됩니다 . 여기에는 반복되는 작은 인라인 스크립트가 제공됩니다.

루프가 반복될 때마다 대상의 해당 디렉터리가 생성되고(로컬 복사본이라고 가정) 사용됩니다 rsync.

한번도 find사용하지 않은관로경로 이름을 안전하게 분리할 수 없는 경우 다른 명령의 경로 이름입니다.

관련된:

관련 정보