다음과 같은 구조의 디렉토리가 있습니다.
-- 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
사용하지 않은관로경로 이름을 안전하게 분리할 수 없는 경우 다른 명령의 경로 이름입니다.
관련된: