以下 shell 脚本如何查找所有大于 20MB 的文件?

以下 shell 脚本如何查找所有大于 20MB 的文件?

我看到一篇文章建议以下内容将查找所有大小大于 20Mb 的文件。

find / -type f -size +20000k -exec ls -lh {} \; 2> /dev/null   | awk '{ print $NF ": " $5 }'  | sort -hrk 2,2

它似乎有效,但我不明白它在 '+20000k' 之后做什么。

答案1

find / -type f -size +20000k -exec ls -lh {} \; 2> /dev/null   | awk '{ print $NF ": " $5 }'  | sort -hrk 2,2
  • /:在主目录中查找启动
  • -type f: 只查找常规文件
  • -size +20000k:大小为 20000k 或以上
  • -exec ls -lh {} \;:对于找到的每个文件执行ls -lh,即以长格式和人类可读大小列出它们(带有后缀“K”,“M”,“G”等)
  • 2>/dev/null:如果find生成任何错误消息,则将它们重定向到黑洞
  • |:将find结果通过管道传输到下一个命令(在本例中为 awk)
  • awk '{print $NF ": " $5}':打印(输出的)最后一个字段,ls -lh后跟冒号,然后是第五个字段。最后一个字段是文件名,第五个字段是文件的大小(采用前面提到的人类可读格式)。
  • |:再次通过管道传输结果(这次是从awkto sort
  • sort -hrk 2,2:仅考虑第二个字段,按人类可读的数字以相反的顺序对结果进行排序。

笔记

您可以更简单、更快地完成此任务,无需使用awksort命令:

find / -type f -size +20000k -exec ls -Shs {} +

在哪里

  • ls -Shs:列出文件,以人类可读的格式打印其大小,同时按大小排序
  • {} +将找到的文件添加到find列表中,并且仅在最后ls对整个列表执行。万一{} \;分别ls在每个文件上运行。

这两个命令之间的唯一区别是,在前一种情况下,大小打印在第二列上,而后者则打印在第一列上。但是,如果文件或目录名称中包含空格,则ls -l每个文件的输出具有不同的列数,因此输出awk或多或少是随机的。换句话说你不应该解析 ls 的输出

答案2

-exec ls -lh {} \;

ls -lh使 find对找到的每个文件执行命令{},' \;' 表示将每个文件分别交给命令。从手册页:

   -exec command ;
          Execute command; true if 0 status is returned.   All  following
          arguments  to  find  are  taken  to be arguments to the command
          until an argument consisting of `;' is encountered.  The string
          `{}'  is  replaced  by  the  current  file name being processed
          everywhere it occurs in the arguments to the command, not  just
          in  arguments  where  it is alone, as in some versions of find.
          Both of these constructions might need to be  escaped  (with  a
          `\')  or  quoted  to  protect them from expansion by the shell.
          See the EXAMPLES section for examples of the use of  the  -exec
          option.   The  specified  command  is run once for each matched
          file.  The command  is  executed  in  the  starting  directory.
          There  are unavoidable security problems surrounding use of the
          -exec action; you should use the -execdir option instead.

2> /dev/null部分确保错误(例如不可读的目录)被丢弃(/dev/null)。

ls -lh一个文件的实际输出如下所示:

-rw-rw-r--  1 anthon users   1,2K Aug 24  2013 sizes.data1

然后进入awk提取文件名(NF 表示字段数)和第 5 个字段的命令(例如sizes.data1: 1.2K:)

这些 name: size 组合通过管道传输到sort第二个字段 ( -k 2,2) 上的排序。用于排序的 -h 与反向排序的 -h 输出相ls -lh匹配-r

答案3

-exec ls -lh {} \; 2> /dev/空

对于每个大于 20MB 的文件,运行带有 -l 和 -h 选项的 ls 命令,并将错误重定向到 /dev/null。

    -l     use a long listing format

    -h, --human-readable
          with -l, print sizes in human readable format (e.g., 1K 234M 2G)

这将创建如下输出:

-rw-r--r--。 1 root root 58M 2012年10月15日 /usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0.x86_64/jre/lib/rt.jar

awk命令:

awk '{ print $NF ": " $5 }'

打印文件名及其大小,$NF 表示最后一列,$5 表示第五列:

/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0.x86_64/jre/lib/rt.jar:58M

最后一个命令:

排序-hrk 2,2

对第二列(即大小)进行反向排序:

   -h, --human-numeric-sort
          compare human readable numbers (e.g., 2K 1G)
   -r, --reverse
          reverse the result of comparisons
   -k, --key=POS1[,POS2]
          start a key at POS1 (origin 1), end it at POS2 (default end of line)

答案4

您可以通过 find 的 -printf 来简化它:

find . -type f -size +20k -printf "%h/%f: %kk\n" | sort -hrk 2,2

但请阅读 find 的联机帮助页,了解 %s 和 %k 之间的微妙之处。 (我拒绝从 / 搜索并用于测试 .,并将大小减小到 +20k,而不是 +20M 来在 .

相关内容