"" 구분 기호가 있는 텍스트 파일로 연결된 매우 작은 파일로 구성된 매우 큰 아카이브가 있습니다. 더 작은 아카이브의 경우 split
""를 패턴으로 사용하여 아카이브한 다음 결과 파일을 처리합니다. 그러나 이 아카이브에는 약 1억 개의 파일이 있습니다. 하나의 디렉토리에 모두 담기에는 너무 많은 것 같습니다. 생성된 디렉터리로 폴더 등을 이동해 보기 위해 폴더 등을 생성했습니다 aa
. ab
그러나 문제가 발생했습니다. 내가 시도한 것들:
split
결과 파일에 대해 명령을 수행 하는 명령이 없습니다 . 그래서 손으로 해야 했어요.**
파일을 디렉토리로 이동하는 것은 파일 이 줄 끝에 있지 않기find . -name "xaa*" -exec mv {} aa \+
때문에 작동하지 않습니다 .{}
-t
내 Unix 버전에서는 소스와 대상을 반전시키는 플래그를 사용할 수 없습니다.find
xargs
이것이 작동하려면 출력을 파이프로 연결해야 합니다 .
그러나 이는 너무 느립니다. 파일이 이동할 수 있는 것보다 훨씬 빠르게 생성됩니다.
xargs
after를 사용하는 것보다 한 번에 처리되는 파일 수가\+
더 적은 것 같습니다find -exec
. 한 번에 6000개의 항목을 실행하기 위해 "-R 6000" 플래그를 추가하려고 시도했지만 이것이 아무런 차이가 없다고 생각합니다.split
우선 순위를 최대한 낮추겠습니다 . 소비하는 CPU 양은 변경되지 않았으므로 영향이 없을 것입니다.명령을 실행하기 위해 최대 7개의 명령 프롬프트(각 명령 프롬프트의 마지막 4글자)를 열었
mv
지만 여전히 충분하지 않았습니다. 더 열어보고 싶었지만 시스템이 7개에 도달하면 응답이 너무 느려서 분할을 중지해야 했습니다. 예를 들어 명령이 무언가를 반환하기를 기다리는 동안ls -l | tail
소스 아카이브가 USB에 복사됩니다.
그래서 제가 한 일은 split
이 시점에서 멈추고 mv
명령이 따라올 때까지 기다린 다음 분할을 다시 시작하는 것입니다. 그때는
find -exec rm {} \+
이미 가지고 있는 파일을 삭제하는 데 사용하는 것이 조금 더 빠르기 때문에 내가 가지고 있지 않은 파일에 도달할 때쯤에는 그 주변에 파일이 더 적어집니다.
따라서 첫 번째 반복은 약 300만 개 파일, 다음 약 200만 개 파일, 다음 약 1.5개 파일 동안 지속되었습니다. 그러나 더 나은 방법이 있을 것이라고 확신합니다. 시도해 볼 만한 다른 아이디어가 있나요?
답변1
이와 같은 작업은 입력 줄당 한 번씩 실행 xargs -I {} ... mv {} aa
됩니다 . mv
~에서POSIX 사양-I
옵션 xargs
:
Insert mode: utility is executed for each logical line from standard input.
실제로 여러 파일에 대해 단일 파일을 실행 xargs -r sh -c 'mv "$@" aa' _
하려면 (또는 그 당시에는) 것과 같은 것이 필요합니다 . 이 방법으로 쉘을 사용하여 대상 디렉토리 사이에 매개변수를 삽입할 수 있습니다.find ... -exec sh -c 'mv "$@" aa' _ {} +
mv
mv
"$@"
필드 분할이나 와일드카드 없이 모든 인수를 사용하여 셸로 대체되었습니다.- 지정된 스크립트와 동일한 효과 가 있습니다
_
. 뒤에 오는 매개변수는 등이거나 집합적입니다.$0
sh -c
$1
$2
$@
그럼에도 불구하고 나는 당신이 find
경쟁 조건에 참여할 것이라고 생각합니다. 완료하기 전에 디렉토리 목록 읽기를 완료 할 수 있으므로 split
모든 파일을 처리하지 못할 수도 있습니다. 또한 생성한 하위 디렉터리로 반복적으로 이동하여 이전에 그곳으로 이동한 파일을 감지하고 다시 이동 aa/xaa
하려고 시도하여 오류가 발생할 수도 있습니다 aa/
(그러나 -exec ... {} +
명령의 종료 상태는 무시됨).