find + xargs - 한 하위 디렉터리에서 다른 하위 디렉터리로 파일 복사/이동

find + xargs - 한 하위 디렉터리에서 다른 하위 디렉터리로 파일 복사/이동

내 폴더 구조는 다음과 같습니다.

/volume1
  /photoTest
    /folderA
      /@eaDir
      /eaDir_tmp 
    /folderB
      /@eaDir
      /eaDir_tmp 
    /folder with space
      /@eaDir
      /eaDir_tmp 

내가하고 싶은 것은 각 폴더의 파일을 eaDir_tmp해당 @eaDir폴더로 복사하는 것입니다.

나는 다음을 통해 그것을 작동시킬 수 있었습니다:

for a in $(find /volume1/photoTest -type d -name eaDir_tmp); do rsync -vhar --chmod=a+rwx $a/ $a/../@eaDir; done;

공백이 있는 폴더를 클릭하기 전까지는 말이죠. 위 스크립트는 완전 쓰레기입니다.

많은 인터넷 검색 끝에 나는 다음을 시도했습니다.

find /volume1/photoTest -type d -name eaDir_tmp -print0 | xargs -0 rsync -vhra --chmod=a+rwx {} {}/../@eaDir

명령의 테스트 실행이 문제 없이 작동했습니다. 그러나 인쇄 후 실제 작업이 중단되었습니다.

sending incremental file list
@eaDir/subdir1/

그리고 그것에 붙어.

ps -elf | grep rsync여러 rsync 프로세스의 시작 wait및 상태를 표시합니다 poll_s.

무슨 일인지 아는 사람 있나요? 해결책은 무엇입니까? 결국 파일을 이동하고 싶지만 문제가 발생하더라도 방해가 되지 않도록 먼저 파일을 복사해 보십시오.

또는 두 가지 명령을 사용하여 작동하게 할 수 있지만 추악한 부분이 많이 있습니다.

# first, copy all files via:    
find /volume1/photo -type d -name eaDir_tmp -exec cp -a -t {}/../@eaDir {}/. \;

# second, change file permissions:    
find /volume1/photo -type d -name @eaDir -exec chmod 777 {} -R \;

그러나 이는 rsync가 수행할 수 있는 작업에 비해 매우 제한적일 뿐만 아니라 느리고 두 배나 오래 걸립니다.

일부 배경 정보:

  • 폴더 안에는 무엇이 들어있나요 eaDir? 더 많은 폴더와 그 안에 있는 일부 파일. 도움이 된다면 모든 것이 시작되는 방법은 다음과 같습니다.https://github.com/mbrrg/synology-thumbgen. 작성자는 기존 @eaDir폴더를 삭제하고 간단히 이름을 바꾸라고 제안했지만 eaDir_tmp기존 폴더에 보관하고 싶은 파일이 포함되어 있기 때문에 그렇게 할 수 없습니다. 설명할 수는 있지만 문제를 더 혼란스럽게 할 것이라고 생각합니다.
  • 이것은 내 Synology NAS DSM 6.0+ 내에 있는데 BusyBox를 실행하고 있다고 가정합니까? 하지만 확실하지 않습니다.
  • 대상 파일이 존재하는 경우 소스 파일이 최신이면 덮어쓰고 싶습니다. 그렇지 않으면 그렇지 않습니다.

답변1

find /volume1/photoTest -type d -name eaDir_tmp -prune \
    -exec sh -c 'rsync -a "$1"/ "${1%/*}/@eaDir"' sh {} ';' \
    -o -type d -name @eaDir -prune

eaDir_tmp그러면 이름이 . 이하인 모든 디렉토리를 찾습니다 /volume1/photoTest. 이러한 각 디렉터리에 대해 다음 명령이 실행됩니다.

rsync -a "$1"/ "${1%/*}/@eaDir"

$1발견된 디렉토리의 경로 이름은 어디에 있습니까? 매개변수 대체는 ${1%/*}경로명의 마지막 구성요소를 제거하여 예를 들어 /volume1/photoTest/folderA/eaDir_tmp( /volume1/photoTest/folderA로 사용할 수도 있음 "$( dirname "$1" )")로 바꿉니다.

eaDir_tmp발견된 컨텐츠와 디렉토리를 찾으면 @eaDir검색 목록에서 제거하고 find입력을 중단합니다. 이것은 으로 이루어집니다 -prune.


수락 :find-execdir

find /volume1/photoTest -type d -name eaDir_tmp -prune \
    -execdir rsync -a eaDir_tmp/ @eaDir ';' \
    -o -type d -name @eaDir -prune

관련된:


사용 zsh:

for dirpath in /volume1/photoTest/*/eaDir_tmp(/DN); do
    rsync -a "$dirpath"/ "$dirpath:h/@eaDir"
done

사용 bash:

shopt -s dotglob nullglob
for dirpath in /volume1/photoTest/*/eaDir_tmp/; do
    rsync -a "$dirpath"/ "$(dirname "$dirpath")/@eaDir"
done

답변2

강타 사용:

for a in volume1/photoTest/*
   do 
      pushd "$a"/eaDir_tmp
      cp -u * ../@eaDir          #... or rsync --chmod...
      popd 
   done

관련 정보