如何在 Linux 终端中查找超过 1GB 的文件夹并执行另一个命令?

如何在 Linux 终端中查找超过 1GB 的文件夹并执行另一个命令?

我想找到大小超过 1GB 的文件夹,然后如果它们超过了,那么我想删除它们。

我发现了一些命令

find /some/path -type d -size +1G -exec ls {} \;

或者

du -h /some/path | grep ^[0-9.]*G

或(超过 600M)

du -h /some/path/ | grep ^[6-9][0-9][0-9][0-9.]*M | sort

但是这两个命令对我没有太大帮助,因为 find 命令找不到任何文件夹,尽管有超过 1GB 的文件夹,但 Linux 认为它们只有一些小 KB。有没有什么命令可以实现这一点?

答案1

处理文件/目录名称时的一个常见问题是它们包含空格。 *nix 文件路径甚至可以包含\n换行符。 要解决所有空格问题,您需要使用无效的定界符\x00

#!/bin/bash
#
# Parameter 1 ("$1"):  Remove sub-directories from this directory
# Parameter 2 ("$2"):  Remove sub-directories larger than this many bytes 
#
# Example, To remove sub-directories bigger than 1 GB from your HOME directory
#   
#    script "$HOME"  $((2**30))     
#        
dir="$1"; shopt -s extglob; dir="${dir%%+(/)}"  # remove trailing / from directory path
[[ -d "$dir" ]] || { echo "\$1: directory NOT found: $1"; exit 1; }

size=$2  # size in bytes
[[ -z $2 || -n ${2//[0-9]} ]] && { echo "\$2: size-threshold must be numeric: $2"; exit 2; }

du -0b "$dir" |                        # output with \x00 as end-of-path
 sort -zrn  |                          # sort dirs,largest first
  awk -vRS="\x00" -vORS="\x00" -v"size=$size" -v"dir=$dir" -v"prev=\x00" '{
     if( $1<=size ) next               # filter by size; skip small dirs
     match( $0, "\x09" )               # find du TAB-delimiter           
     path = substr( $0, RSTART+1 )     # get directory path 
     if( path ~ "^"dir"/*$" ) next     # filter base dir; do not kill it! 
     match( path, "^" prev ".+" )      # print (ie. process) parent dirs only
     if( RSTART == 0 ) { print path }
     prev = path }' |
   xargs -0 -I{} echo rm -vr {}        # remove the `echo` to run live!!!!

答案2

要查找大于 10G 的文件夹: du -h /mnt/backup/ |awk '$1 ~ /[0-9]*G/ {print}' |sort -nr|sed 's/G//g' |awk '{ if ( $1 > 10.0 ) print }'

您可以将 10.0 更改为任意数字,并将 /mnt/backup 更改为任意路径,它将打印出与其大小(以 GB 为单位)匹配的文件夹。

答案3

您所要求的是一个糟糕的想法。这主要是因为您要求的工作方式:如果文件夹foo包含超过 1GB 的内容,则 的每个父文件夹foo也包含超过该内容的内容(因为它包含文件夹foo)。

因此,如果您扫描/home/myuser/myfolder/较大的内容,并且/home/myuser/myfolder/bar/quz/baz/foo、、/home/myuser/myfolder/bar/quz/baz/home/myuser/myfolder/bar/quz/ /home/myuser/myfolder/bar//home/myuser/myfolder/将被标记为删除。

您可以使用 du 的 -S 选项来解决此问题。

这给出了一个结果(我不建议运行)

du -Sb $DIR | grep '^[0-9]\{10\}' | cut -f 2- | xargs -d "\n" rm -rf

这会对名称包含换行符的目录失败。如何修复此问题留给读者练习。

如果您想要其他大小,请编写一个正则表达式来匹配它。du -b返回以字节为单位的大小,因此从那里开始。提示:365MB 或更大'^\([0-9]\{10\}\|[4-9][0-9]\{8\}\|3[7-9][0-9]\{7\}\|36[6-9][0-9]\{6\}\)'

答案4

使用du -h获取文件和目录及其大小的列表。然后,您可以使用sed提取要删除的文件夹名称并将它们传递给rm。这可以作为 bash 脚本或您喜欢的任何 shell 上的命令来实现。如果您在编写命令时需要更多帮助,请告诉我。不过,阅读上述命令的手册页应该可以帮助您完成任务。

相关内容