크기에 따라 파일을 재귀적으로 이동하고 구조를 유지하는 방법

크기에 따라 파일을 재귀적으로 이동하고 구조를 유지하는 방법

각 파일이 하위 폴더에 있는 디렉터리 트리에서 "300Mb"보다 큰 파일을 이동하고 싶습니다.

예: 다음과 같은 디렉터리 구조가 있습니다.

dirA/
dirA/file1
dirA/x/
dirA/x/file2
dirA/y/
dirA/y/file3

이는 각 파일이 하위 폴더로 이동되는 디렉터리 트리의 "이동"인 예상 결과입니다.

dirB/            #  normal directory
dirB/file1       #  moved from dirA/file1
dirB/x/          #  normal directory
dirB/x/file2     #  moved from dirA/x/file2
dirB/y/          #  normal directory
dirB/y/file3     #  moved from dirA/y/file3

그런데 find /path/ -type f -size +300m그러면 어쩌죠? 안타깝게도 일부 파일에는 키보드에서 찾을 수 있는 다양한 문자가 포함되어 있습니다.

나는 이것을 보고 있었다철사얘기는 있는데 cpio그 프로그램은 잘 모르겠네요...

PS: GNU Parallel을 설치하면 속도가 빨라질 수 있나요?

답변1

가장 간단한 방법은다루기 힘든. 당신은 그것을 사용할 수 있습니다글로벌 예선파일 형식, 크기 등의 기준에 따라 파일을 일치시킵니다. 이것와일드카드 패턴 **/모든 수준의 하위 디렉터리와 일치합니다. 이것기록 수정자 ht디렉토리와 파일 이름의 기본 부분을 추출하는 간단한 방법입니다 . 디렉터리 생성은 필요할 때 호출됩니다 mkdir -p.

cd dirA
for x in **/*(.Lm+300); do
  mkdir -p ../dirB/$x:h &&
    mv -- $x ../dirB/$x
done

이식 가능한 방법은 find. -exec조각을 사용하여 각 파일에 대한 셸을 호출하는 것입니다.

cd dirA
find . -type f -size +300000k -exec sh -c 'for x do
  mkdir -p "../dirB/${x%/*}"
  mv "$x" "../dirB/$x"
done' sh {} +

병렬화는 입력/출력에 거의 유용하지 않습니다. 병렬화를 사용하면 여러 CPU를 활용할 수 있지만 CPU가 I/O에 병목 현상을 일으키는 경우는 거의 없습니다.

답변2

Perl이 rename확실한 선택입니다. ren, rename또는 다음 과 같이 설치할 수 있습니다 pren.

find dirA -type f -size +300M | ren 's:^dirA/:dirB/:'

그러나 파일을 다른 마운트 지점으로 이동하면 작동하지 않으며 디렉터리가 존재하지 않으면 실패합니다.

GNU Parallel은 속도가 느려집니다.

cd dirA
find . -type f -size +300M | parallel mkdir -p ../dirB/{//}
find . -type f -size +300M | parallel mv {} ../dirB/{}

그러나 파일을 다른 파일 시스템으로 이동하기 위해 복사 및 삭제 루틴을 수행해야 하는 경우에도 작동합니다.

답변3

간단히 말해서:

find dirA -type f -size +300m -printf "mv %p dirB/%P\n" | sh

그러나 시작하기 전에 dirB의 모든 하위 디렉터리가 존재해야 합니다. 이렇게 하려면 다음 두 단계를 따르는 것이 좋습니다.

cd dirA
find . -type f -size +300m -printf "mkdir -p ../dirB/%h\nmv %p ../dirB/%P\n" | sh

cpio 관련(실제로 하위 디렉토리 문제 해결):

(cd dirA; find . -type f -size +300m) | cpio -p -md  dirB

(당신이 언급한 같은 스레드의 cp(1)에 관해서 이것은 복사하기 때문에 당신에게 좋지 않습니다. 모두 문서 그리고 dirB 아래에 dirA라는 하위 디렉터리를 만듭니다. 배너-티이 문제를 해결할 수 있습니다)

답변4

이는 이를 재정의해야 합니다.

find /path -type f -size +300m | while read A ; do DEST=${A/dirA/dirB} ; echo mkdir -p $(dirname $DEST) 2>/dev/null; echo mv $A $DEST ; done

먼저 있는 그대로 실행하고 상태 검사를 수행한 후 제안된 명령이 만족스러우면 echo요소 없이 다시 실행하세요.

파일 구조 예에서는 다음 명령이 생성됩니다.

mkdir -p ./dirB
mv ./dirA/file1 ./dirB/file1
mkdir -p ./dirB/x
mv ./dirA/x/file2 ./dirB/x/file2
mkdir -p ./dirB/y
mv ./dirA/y/file3 ./dirB/y/file3

관련 정보