如何使用 find 来选择具有一定磁盘空间使用量的用户?

如何使用 find 来选择具有一定磁盘空间使用量的用户?

我想查找/home/目录中显示的所有磁盘占用量超过 500MB 的用户。以下命令按预期工作。

cd /home/ && du */ -hs
68K     ajay/
902M    john/
250M    websites/

从上面的例子来看,只902M john/应该返回。

我怎样才能让find命令输出相同的结果?

答案1

您不能只使用 find 来执行此操作,因为 find 作用于单个文件,并且没有添加文件大小的概念。您可以将 find 的输出导入另一个工具,但是既然 du 可以完成大部分工作,为什么还要费心呢?

du -sm */ | sort -k1,1n | awk '$1 > 500 { sub(/$/, "M", $1); print $0 }'

当输入中包含“人类可读”后缀时,awk 测试会变得混乱,因为您需要删除尾随的“M”才能进行整数比较。对于输出,我个人会跳过“M”后缀,但这就是要求。

答案2

不确定你为什么想要这样的东西find,所以这里有一个脚本可以执行你要求的操作bash(但不像 find 那样工作):

max_size=$((500*1024))
cd /home/ && du -ks */ | while read size user ; do
  if [ $size -gt $max_size ] ; then
    echo "${user%/} exceeds quota"
  fi
done

示例:(尺寸较小):

$ du -sk */
2948    a/
4       a b/
640     b/
48      qt/

$ du -ks */ | while read size user ; do if [ $size -gt 600 ] ; then echo "${user%/} exceeds quota" ; fi ; done
a exceeds quota
b exceeds quota

${user%/}为了更加美观,只需删除结尾的斜杠即可。

答案3

这将打印每个用户文件的磁盘使用情况(以 kb 为单位),无论dir这些文件位于何处:

find dir -printf "%u %b\n" | perl -n -e '@l = split; $sum{$l[0]} += $l[1]; END { foreach(sort(keys(%sum))) { print "$_ ",$sum{$_}/2," KiB\n"; }}'

find 命令打印出 中每个文件和目录的所有者和块数dir。perl 命令将使用情况添加到以用户名为关键字的哈希中,从而构建每个用户文件大小的总和;然后打印出哈希的内容。

答案4

以答案形式发布。

我用过杜女士获得一致的输出,无需额外干预即可由 awk 处理。您说得对,人类可读的输出更好,因此最终输出会再次被处理。

#!/bin/bash

######################################################################
#  AUTHOR: Joe Negron - LOGIC Wizards ~ NYC
#  LICENSE: BuyMe-a-Drinkware: Dual BSD or GPL (pick one)
#  USAGE: byteMe (bytes)
#  ABSTRACT: Converts a numeric parameter to a human readable format.
#  URL: http://www.logicwizards.net/2010/10/19/byteme-a-simple-binary-metrics-bash-script-howto-convert-bytes-into-kb-mb-gb-etc-using-bash-bc/
######################################################################
function byteMe() { # Divides by 2^10 until < 1024 and then append metric suffix
declare -a METRIC=('B' 'KB' 'MB' 'GB' 'TB' 'XB' 'PB') # Array of suffixes
MAGNITUDE=0  # magnitude of 2^10
PRECISION="scale=1" # change this numeric value to inrease decimal precision
UNITS=`echo $1 | tr -d ','`  # numeric arg val (in bytes) to be converted
while [ ${UNITS/.*} -ge 1024 ] # compares integers (b/c no floats in bash)
  do
   UNITS=`echo "$PRECISION; $UNITS/1024" | bc` # floating point math via `bc`
   ((MAGNITUDE++)) # increments counter for array pointer
  done
echo -n "$UNITS${METRIC[$MAGNITUDE]}"
}

cd /home/ && du */ -bs | awk '$1 > 500 { print $0 }' | while read LINE; do
    SIZE=$(echo "$LINE" | cut -f 1)
    HRSIZE=$(byteMe "$SIZE")
    DIR=$(echo "$LINE" | cut -f 2)
    printf "%8s %s\n" "$HRSIZE" "$DIR"
done

笔记:

  1. 通过谷歌搜索找到了 bash 函数(参见评论)
  2. 我变了杜女士杜伯斯,从而可以使用接受字节的转换函数。
  3. 500MB 限制仍是硬编码的。您可以随意修改脚本以将其作为参数接受。

相关内容