"분할" 속도를 늦추세요

"분할" 속도를 늦추세요

"" 구분 기호가 있는 텍스트 파일로 연결된 매우 작은 파일로 구성된 매우 큰 아카이브가 있습니다. 더 작은 아카이브의 경우 split ""를 패턴으로 사용하여 아카이브한 다음 결과 파일을 처리합니다. 그러나 이 아카이브에는 약 1억 개의 파일이 있습니다. 하나의 디렉토리에 모두 담기에는 너무 많은 것 같습니다. 생성된 디렉터리로 폴더 등을 이동해 보기 위해 폴더 등을 생성했습니다 aa. ab그러나 문제가 발생했습니다. 내가 시도한 것들:

  1. split결과 파일에 대해 명령을 수행 하는 명령이 없습니다 . 그래서 손으로 해야 했어요.

  2. **파일을 디렉토리로 이동하는 것은 파일 이 줄 끝에 있지 않기 find . -name "xaa*" -exec mv {} aa \+때문에 작동하지 않습니다 .{}

  3. -t내 Unix 버전에서는 소스와 대상을 반전시키는 플래그를 사용할 수 없습니다.

  4. findxargs이것이 작동하려면 출력을 파이프로 연결해야 합니다 .

그러나 이는 너무 느립니다. 파일이 이동할 수 있는 것보다 훨씬 빠르게 생성됩니다.

  1. xargsafter를 사용하는 것보다 한 번에 처리되는 파일 수가 \+더 적은 것 같습니다 find -exec. 한 번에 6000개의 항목을 실행하기 위해 "-R 6000" 플래그를 추가하려고 시도했지만 이것이 아무런 차이가 없다고 생각합니다.

  2. split우선 순위를 최대한 낮추겠습니다 . 소비하는 CPU 양은 변경되지 않았으므로 영향이 없을 것입니다.

  3. 명령을 실행하기 위해 최대 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' _ {} +mvmv

  • "$@"필드 분할이나 와일드카드 없이 모든 인수를 사용하여 셸로 대체되었습니다.
  • 지정된 스크립트와 동일한 효과 가 있습니다 _. 뒤에 오는 매개변수는 등이거나 집합적입니다.$0sh -c$1$2$@

그럼에도 불구하고 나는 당신이 find경쟁 조건에 참여할 것이라고 생각합니다. 완료하기 전에 디렉토리 목록 읽기를 완료 할 수 있으므로 split모든 파일을 처리하지 못할 수도 있습니다. 또한 생성한 하위 디렉터리로 반복적으로 이동하여 이전에 그곳으로 이동한 파일을 감지하고 다시 이동 aa/xaa하려고 시도하여 오류가 발생할 수도 있습니다 aa/(그러나 -exec ... {} +명령의 종료 상태는 무시됨).

관련 정보