rsync를 사용하여 .mp3 파일이 포함된 디렉터리만 복사

rsync를 사용하여 .mp3 파일이 포함된 디렉터리만 복사

.mp3 파일이 포함된 폴더만 다른 장치에 복사하려고 합니다.그리고 .mp3만. 구조는 다음과 같습니다.

Band/Year - Album/*.flac
Band/Year - Album/*.txt
Band/Year - Album/*.mp3
Band/Year - Album/covers
Band/Year - Album/covers/*.jpg

많은 매뉴얼과 포럼을 읽었지만 문제를 해결할 수 없습니다. 내가 뭘 하든, 카피에 담고 싶은 것을 어떻게 공식화하려고 하든 그건 제외되기 때문에, 심지어 사라지기도 한다.

--exclude=* --include=*

아무것도 복사되지 않습니다. 디렉토리 없이도 다른 디렉토리에서 테스트했습니다. 젠장.

편집: 내가 시도했지만 아무 소용이 없었던 목록:

rsync -rnv --exclude=** --include=*/ --include=*/*/ --include=*/*/*/ --include=*/*/*.mp3 "./Be'lakor" /media/moorindal/WALKMAN/MUSIC
rsync -rnv --exclude=** --include=*/ --include=*/*/ --include=*/*/*/ --include=**.mp3 "./Be'lakor" /media/moorindal/WALKMAN/MUSIC
rsync -rnv --exclude=** --include=*/ --include=*/* --include=**.mp3 "./Be'lakor" /media/moorindal/WALKMAN/MUSIC
rsync -rnv --exclude=*/*/* --include=**.mp3 "./Be'lakor" /media/moorindal/WALKMAN/MUSIC
rsync -rnv --exclude=*/*/*.* --include=**.mp3 "./Be'lakor" /media/moorindal/WALKMAN/MUSIC
rsync -rnv --exclude='*/*/*.*' --include='*/*/*.mp3' "./Be'lakor" /media/moorindal/WALKMAN/MUSIC

답변1

첫째, --exclude=* --include=*작동하지 않는 이유: 첫 번째 일치 규칙이 적용되기 때문입니다. *모든 것과 일치하므로 모든 것이 제외되고 rsync는 어떤 파일에도 두 번째 규칙을 시도하지 않습니다. 바라보다Rsync 필터: 하나의 패턴만 복사rsync 필터에 대한 가이드입니다.

.mp3필요한 파일을 포함하려면

rsync -a -m --include='*.mp3' --include='*/' --exclude='*'

즉, MP3를 포함하고 모든 디렉터리를 포함하며(디렉토리를 포함하지 않으면 디렉터리에 어떤 파일도 포함하지 않음) 다른 모든 항목을 제외합니다. 이 -m옵션(일명 --prune-empty-dirs)을 사용하면 rsync가 복사할 파일이 포함되지 않은 디렉터리를 건너뛰게 됩니다. 그러나 .mp3이 파일과 동일한 디렉터리에 있는 다른 파일은 포함되지 않습니다 . 이렇게 하려면 셸이나 다른 도구의 도움이 필요합니다.

zsh에서는 .mp3하위 디렉터리의 파일을 일치시킨 **/*.mp3다음 사용할 수 있습니다.기록 수정자로서글로벌 예선결과를 .mp3파일이 포함된 디렉터리 목록으로 변환합니다.

rsync -a **/*.mp3(:h) /destination

디렉터리가 너무 많으면(또는 더 정확하게는 이름을 합친 길이가 너무 큰 경우) 명령줄 제한이 깨질 수 있습니다. 중복 항목을 제거하면 도움이 될 수 있습니다.

typeset -aU directories
directories=(**/*.mp3(:h))
rsync -a $directories /destination

이는 명령이 너무 길어질 위험을 제거하는 것이 아니라 단지 명령의 길이를 줄이는 것뿐입니다. 위험을 제거하려면 다음을 사용하십시오.zargsrsync를 일괄적으로 실행합니다.

autoload -U zargs
typeset -aU directories
directories=(**/*.mp3(:h))
do_rsync () { rsync -a $@ /destination; }
zargs --max-chars=$(($(get_conf ARG_MAX) - 500)) -- $directories -- do_rsync

답변2

rsync로 너무 많은 일을 하고 싶습니다. 가장 먼저 할 일은 모든 MP3 파일 목록을 생성하는 것입니다.

find Music -type f -iname '*.mp3'

그런 다음 파일 목록은 파일이 포함된 디렉터리 목록으로 변환됩니다.

sed 's:/[^/]*$::'

목록에서 중복된 디렉터리를 제거합니다.

sort -u

이제 필요한 디렉토리 목록이 생겼습니다. 한 번에 하나씩 rsync하도록 피드하세요. 대상 디렉토리 트리를 그대로 유지하려면 --relative를 사용하십시오.

while IFS= read -r dir; do rsync --archive --relative "$dir" /mnt; done

전체적으로 파이프라인으로:

find Music -type f -iname '*.mp3' |
   sed 's:/[^/]*$::' |
   sort -u |
   while IFS= read -r dir; do rsync --archive --relative "$dir" /mnt; done

답변3

--include이런 상황에 대해 걱정 하거나 초조해할 필요가 없습니다 --exclude. 잘 구조화되고 알려진 위치에 있는 파일을 rsync복사하도록 지시하면 됩니다 .mp3

cd /path/to/source
rsync -avR */*/*.mp3 /path/to/target/

아마도 당신은 mp3잘 구조화된 레이아웃을 가정하여 이 작은 루프를 사용하여 복사할 수 있습니다.

for mp3 in */*/*.mp3
do
    rsync --exclude covers -avR "${mp3%/*}"/ /path/to/target/
done

관련 정보