~/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 du
sum 구현을 사용하여 임의의 파일 이름을 처리하려면 다음을 수행할 수 있습니다 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 --)
)
그건:
- 블록 크기를 지정합니다. 그렇지 않으면
du
GNU에서 사용하는 블록 크기는 환경에 따라 다릅니다. 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가 du
POSIX에서 요구하는 대로 블록 크기로 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