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