기본적으로 BSD인 터미널에서 MacOS를 실행하므로 질문하는 것보다 여기에 질문을 게시하는 것이 다릅니다. 다음 단계에서 파일을 무작위로 삭제하여 이미지 데이터세트를 정리하고 싶습니다. 일부 카탈로그에는 1백만 개가 넘는 jpg가 있습니다. 내 데이터는 기본 디렉터리에 있고 하위 디렉터리의 최대 깊이는 1입니다.
-master
-data1
image.jpgs
-data2
image.jpgs
-data3
image.jpgs
-data4
image.jpgs
... and so forth
다음 링크를 찾았습니다.
https://superuser.com/questions/1186350/delete-all-but-1000-random-files-in-a-directory
...그리고 생각해낸 결과는 다음과 같습니다.
for f in *.jpg; do find "$f" -type f -print0 | sort -R | tail -n +50001 | xargs -0 rm; done
작동하는 동안 하위 디렉터리에 대해 이 작업을 반복적으로 수행하여 각 디렉터리에 대해 수동으로 수행할 필요가 없도록 하고 싶습니다. 내 질문/요구 사항은 다음과 같습니다.
- 속도를 높이기 위해 어떻게든 최적화할 수 있나요?
- 50,000개 미만의 파일이 있는 디렉터리를 발견하면 sort/tail이 오류를 반환합니까?
답변1
링크된 소스 게시물을 확인한 후 루프가 실제로 다음과 같아야 합니다.
for d in */; do find "$d" -iname '*.jpg' -type f -print0 | sort -zR | tail -zn +50001 | xargs -0r rm; done
디렉토리에서 실행하십시오 master
.
-z
입력이 Null로 구분되므로 및 옵션이 필요합니다. 행이 50,000개 미만인 경우에도 불평하지 않습니다. 행 50,000개 이후에는 아무 것도 없기 때문에 아무 것도 신경쓰거나 인쇄하지 않습니다. 인수 없이 실행하는 것에 대해 불평할 수 있지만 GNU의 옵션은 입력 없이 실행되는 것을 방지합니다(BSD xargs는 이를 요구하지 않지만 아마도 불평하지 않을 것입니다).sort
tail
sort
tail
rm
-r
xargs
rm
마지막으로 -z
BSD tail은 null로 구분된 입력 옵션을 지원하지 않을 수 있습니다. homebrew를 사용하여 설치할 수 있는 GNU tail이 필요합니다.
파일 이름에 공백, 개행, 따옴표, 백슬래시 등이 포함되지 않는 것이 보장된다면 줄을 구분하기 위해 공백이 필요하지 않을 것입니다. 이 경우:
for d in */; do find "$d" -type f | sort -R | tail -n +50001 | xargs rm; done