~/foo
我正在一个有子目录的目录中工作
~/foo/alpha
~/foo/beta
~/foo/epsilon
~/foo/gamma
我想发出一个命令,检查每个“1 级”子目录下的总大小,~/foo
如果大小低于给定值,则删除该目录及其内容。
因此,假设我想删除内容小于50K
.发出$ du -sh */
退货单
8.0K alpha/
114M beta/
20K epsilon/
1.2G gamma/
我希望我的命令能够删除~/alpha
及其~/epsilon
内容。有这样的命令吗?我怀疑这可以通过某种方式完成find
,但我不太确定如何完成。
答案1
使用 GNUfind
和 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
和,要处理任意文件名,您可以执行以下操作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 --)
)
那是:
- 指定块大小,否则 GNU
du
使用的块大小取决于环境。 1 保证您获得最大精度(您获得以字节数为单位的磁盘使用情况)。 - 用于
-0
处理以 NUL 分隔的记录(NUL 是文件路径中唯一可能找不到的字符)。 -d1
只获取深度不超过 1 的目录的累积磁盘使用情况(深度 0 (.
) 被 in 排除在外!/^[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
是为了 GNUdu
确保它按照 POSIX 的要求使用 512 作为块大小)。
答案3
我知道这有点老了,但我自己有 0.02 美元来做这件事,希望它能帮助其他人。使用 GNU 并行可以获得更好的并行性能:
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