내용이 주어진 크기보다 작은 디렉토리를 삭제하는 명령

내용이 주어진 크기보다 작은 디렉토리를 삭제하는 명령

~/foo하위 디렉터리가 있는 디렉터리에서 작업 중입니다.

~/foo/alpha
~/foo/beta
~/foo/epsilon
~/foo/gamma

~/foo각 "레벨 1" 하위 디렉터리 아래의 전체 크기를 확인하고 크기가 지정된 값보다 작은 경우 디렉터리와 해당 내용을 삭제하는 명령을 실행하고 싶습니다 .

따라서 .보다 작은 콘텐츠를 삭제하고 싶다고 가정해 보겠습니다 50K.$ du -sh */

8.0K alpha/
114M beta/
20K  epsilon/
1.2G gamma/

~/alpha내 명령으로 해당 내용 과 해당 내용을 삭제할 수 있기를 원합니다 ~/epsilon. 그런 명령이 있나요? 나는 이것이 어떻게든 이루어질 수 있다고 생각 find하지만, 어떻게 될지는 잘 모르겠습니다.

답변1

GNU find및 GNU를 사용 coreutils하고 디렉터리 이름에 줄 바꿈이 없다고 가정합니다.

find ~/foo -mindepth 1 -maxdepth 1 -type d -exec du -ks {} + | awk '$1 <= 50' | cut -f 2-

그러면 총 콘텐츠가 50K 미만인 디렉터리가 나열됩니다. 결과에 만족하여 이를 제거하려면 | xargs -d \\n rm -rf명령줄 끝에 추가하십시오.

답변2

GNU dusum 구현을 사용하여 임의의 파일 이름을 처리하려면 다음을 수행할 수 있습니다 awk.xargs

(
  cd ~/foo &&
    du --block-size=1 -l0d1 |
      awk -v RS='\0' -v ORS='\0' '
        $1 < 50*1024 && !/^[0-9]+\t\.$/ && sub("^[^\t]+\t", "")' |
      xargs -r0 echo rm -rf --)
)

그건:

  • 블록 크기를 지정합니다. 그렇지 않으면 duGNU에서 사용하는 블록 크기는 환경에 따라 다릅니다. 1은 최대 정확도를 보장합니다(디스크 사용량을 바이트 단위로 얻음).
  • NUL로 구분된 레코드를 처리 하는 데 사용됩니다 -0. NUL은 파일 경로에서 찾을 수 없는 유일한 문자입니다.
  • -d1깊이가 1 이하인 디렉터리에 대해서만 누적 디스크 사용량을 가져옵니다(깊이 0( .)은 에서 제외 !/^[0-9]\t\.$/) awk.
  • -l파일의 디스크 사용량이 첫 번째 디렉터리뿐만 아니라 항목으로 발견된 모든 디렉터리에 대해 계산되는지 확인하세요.

실제로 이 작업을 수행하려면 제거 echo(테스트 실행)하세요.

또는 perl대신 사용하십시오 gawk:

perl -0ne 'print $2 if m{(\d+)\t(.*)}s && $1 < 50<<10'

POSIXly에는 다음과 같은 것이 필요합니다.

(
  unset -v BLOCK_SIZE BLOCKSIZE DU_BLOCKSIZE
  cd ~/foo &&
   LC_ALL=C POSIXLY_CORRECT=1 find . ! -name . -prune -type d -exec sh -c '
     for dir do
       du -s "$dir" | awk '{exit $1<50*1024/512 ? 41 : 0}'
       [ "$?" -eq 41 ] && echo rm -rf "$dir"
     done' sh {} +
)

( unset -v BLOCK_SIZE BLOCKSIZE DU_BLOCKSIZE그리고 POSIXLY_CORRECT=1이는 GNU가 duPOSIX에서 요구하는 대로 블록 크기로 512를 사용하는지 확인하기 위한 것입니다.)

답변3

나는 이것이 약간 오래되었다는 것을 알고 있지만 이 작업을 수행하기 위해 내 자신의 $0.02가 있었고 그것이 다른 사람에게 도움이 되기를 바랍니다. GNU Parallel을 사용하면 더 나은 병렬 성능을 얻을 수 있습니다.

find . -type d | parallel du -s {} | sort -h

이렇게 하면 PWD에 있는 모든 디렉터리의 크기가 크기별로 정렬되어 출력됩니다. 역순 정렬:

find . -type d | parallel du -s {} | sort -hr

다음 sort -h과도 작동합니다 du -h.

~  VirtualBox VMs  $  find . -type d | parallel du -sh {} | sort -h
4.0K    ./CentOS6/dir with spaces
4.0K    ./TFE79/Snapshots
8.0K    ./Desktop_default_1614944927311_69927/Logs
8.0K    ./Desktop_default_1614945289369_20675/Logs
12K     ./Desktop_default_1614944927311_69927
12K     ./Desktop_default_1614945289369_20675
96K     ./hello-world/Logs
108K    ./hello-world
160K    ./Knoppix/Logs
172K    ./Desktop_default_1627485664080_37244/Logs
172K    ./Knoppix
208K    ./CentOS6/Logs
228K    ./Flash/Logs
880K    ./TFE8/Logs
980K    ./TFE79/Logs
260M    ./NomadOS
411M    ./Desktop_default_1627485664080_37244/Snapshots
4.5G    ./CentOS6
6.6G    ./Flash
9.4G    ./TFE8/Snapshots
13G     ./TFE8
15G     ./Desktop_default_1627485664080_37244
18G     ./TFE79
56G     .

답변4

첫 번째 답변은 잘 작동하지만 공백이 포함된 디렉터리 이름에는 작동하지 않습니다. (이것은 50Kb 이상이기 때문에 올바른 논리입니다)

#RESULTTODELETE=$(find ~/foo -mindepth 1 -maxdepth 1 -type d -exec du -ks {} + | awk '$1 <= 50' | cut -f 2-); RESULTTODELETE2=$(echo "$RESULTTODELETE" | sed 's, ,\\ ,g'); echo "$RESULTTODELETE2" | xargs rm -rf

할 것이다:

~/f oo/a lpha
~/fo o/be ta
~/f o o/ep silon
~/foo/gamma

관련 정보