递归查找最大文件

递归查找最大文件

我试图递归地找到目录中最大的文件。如果该目录内有子目录,则该函数需要进入该目录并检查最大的文件是否在那里。一旦找到最大的文件,输出就会显示,其中包含相对路径名以及最大文件的名称和大小。

前任:

dude@shell2 (~...assignment/solutions) % bash maxfile.sh ~/test
class/asn
dude.h.gch: 9481628

这就是我所拥有的:

#!/bin/sh
clear

recursiveS() {
    for d in *; do
        if [ -d $d ]; then
            (cd $d; echo $(pwd)/$line; du -a; recursiveS;)
        fi
    done
}
recursiveS

我已经被困了一段时间了。我无法通过管道化许多现有的 Unix 工具来实现这一点。任何想法都会很好!

答案1

使用find(这里假设 GNU find)输出文件名和文件大小。种类。打印出最大的一个。

find . -type f -printf "%s\t%p\n" | sort -n | tail -1

假设文件路径不包含换行符。


bash在 GNU 实现中使用循环stat

shopt -s globstar
max_s=0
for f in **; do
  if [[ -f "$f" && ! -L "$f" ]]; then
    size=$( stat -c %s -- "$f" )
    if (( size > max_s )); then
      max_s=$size
      max_f=$f
    fi
  fi
done
echo "$max_s $max_f"

这将比查找解决方案慢得多。这还假设文件名不以换行符结尾,并且将跳过隐藏文件并且不会进入隐藏目录。

如果当前目录中有一个文件被调用-,则将考虑在标准输入上打开的文件的大小。

请注意,4.3 之前的版本bash在下降目录树时遵循符号链接。

答案2

此命令也有助于列出定义的大小。

find . -type f -size +100M -exec ls -lh {} \;

答案3

这适用于 BSD/macOS 并使用快速但非 POSIX 的实用程序-ls扩展find

find . -type f -ls | sort -k7 -r | head -n 3

这速度较慢,但​​可能适用于-ls扩展在以下位置不可用的POSIX 系统find

find . -type f -exec ls -al {} \; | sort -k5 -r | head -n3

怎么运行的:

  • find是一个功能强大的文件搜索实用程序,它将根据下面解释的给定查询向您显示结果。
  • find .将在当前工作目录中搜索。
  • find . -type f将仅搜索指定的文件类型“f”,即常规文件(这意味着它将跳过目录、特殊文件、链接、套接字等)。
  • -ls开关将指示find显示有关找到的文件的完整信息。然而,根据 BSD 系统上的 man 的说法,它是 IEEE Std 1003.1-2001(“POSIX.1”)标准的扩展,可能不适用于所有平台。
  • 或者,如果-ls扩展在您的系统上不可用,您可以-exec .. {} \;使用ls -al命令并使用第 5 个字段对结果进行排序。{}表示已找到的文件名。\;包含-exec命令。
  • |Unix 符号的意思是“管道”,即将一个程序的输出重定向到另一个程序的输入。它将发送find程序输出文本作为sort程序的输入。
  • sort是一个排序实用程序。它获取数据行,然后按升序对这些行进行排序作为结果。
  • sort -k7表示将第7个字段作为排序参数值。参数由空格分隔。第 7 个参数是实用程序生成的文件大小find。如果你使用-exec ls -al {} \;而不是-ls那么你将使用第五个字段-k5来排序。
  • -r告诉sort使用反向排序,将最大的放在前面。因为我们想首先查看最大的文件。
  • 此外,如果您确实不想看到数百行,您还可以|将排序的输出通过管道 ( ) 传输到head实用程序,该实用程序将只显示结果输出的前三行(按照 的指示)。-n 3

长话短说:用于查找递归常规文件,仅在当前工作目录中开始搜索,然后使用扩展名(或执行)find显示有关该文件的完整信息。稍后使用 unix 管道将结果传递给to ,并根据第 7 个(或第 5 个)字段使其首先排序最大。此外,您可以使用实用程序将结果限制为行。-lsls -alfindsort|nhead

我的意思是“使用 Brainz”让你阅读“man”并自己离线搜索解决方案,这将训练你从头开始解决问题:-)

答案4

此外斯蒂芬·查泽拉斯' 回复,我想添加以下注释(我无法发表评论):

  1. 要获得最小的常规文件,请使用o而不是O
ls -ld -- **/*(.DoL[1])
  1. 您可以通过将具体(或多个)扩展名附加到通配符来进行过滤**/*
ls -ld -- **/*.png(.DoL[1])
ls -ld -- **/*.{png, jpg}(.DoL[1]) # this will give two results, one per extension

相关内容