打印出小于指定文件大小的文件列表

打印出小于指定文件大小的文件列表

我正在尝试创建一个脚本,可以执行该脚本来搜索文件列表,将文件大小字段与指定的文件大小进行比较,然后显示小于指定文件大小的文件。

我知道我必须使用“ls -l”才能获取详细的文件列表。但是,我该如何搜索列表并提取文件呢?

答案1

你的方法很笨拙(公平地说错误的)。find其中之一就是有专门的工具来完成此类任务。

例如,要递归查找当前目录中小于 1 MiB(1048576 字节)的所有文件:

find . -type f -size -1048576c

或者使用提供此类基于大小的 glob 限定符的 shell,例如zsh,递归地:

print -rl -- **/*(.L-1048576)

这里,与上面相反find,没有隐藏文件。添加Dglob 限定符以包含它们。

答案2

解析 的输出时要记住的事情ls -l

  • 格式取决于区域设置。该格式仅由 POSIX/C 语言环境中的 POSIX 指定,即使如此,它也允许一些变化(例如字段之间的间距、第一个字段的宽度...)。例如,您无法轻松检测以空白字符开头的可移植文件名。
  • 许多系统允许用户名和组名中存在空格,这使得可靠地解析输出几乎是不可能的。最好是使用ls -n(使用数字用户 ID)而不是ls -l.
  • ls如果文件名可能包含换行符(并且几乎所有 POSIX 系统中的文件名中都允许换行符),则不可能可靠地解析 的输出,除非您使用该-q选项(但是您无法说出确切的文件名,只需查看引用的表示形式,您无法从中返回原始文件名)或使用某些实现中发现的非标准选项。但另请参阅下面的技巧。
  • 尺寸并非所有类型的文件都提供该字段(并且该字段的含义尺寸对于某些类型的文件,字段因系统而异)。您可能希望限制为常规文件。
  • 以上假设是 POSIX ls。已知旧版本具有不同的输出格式,或者在某些情况下字段之间缺少空格......

因此,考虑到这一点,只要您可以保证文件名不包含换行符并且不以空白字符开头,要列出大小严格小于 1MiB 的常规文件,您可以这样做:

(
  export LC_ALL=C
  ls -n | awk '
    /^-/ && $5 < 1048576 { 
      gsub(/([^[:blank:]]+[[:blank:]]+){8}/, "")
      print
    }'
)

-a如果您想包含隐藏文件,请添加该选项。添加-L如果对于符号链接,您想要考虑它们(最终)解析到的文件。

正如其他人所说,正确的解决方案是在find这里使用。

避免换行和前导空白问题的技巧。

ls -n如果我们使用代替ls -nd ./*,我们将能够知道文件名从哪里开始(在 上./)以及在哪一行结束(在下一个 之前的行上./),所以你可以这样做:

(
  export LC_ALL=C
  ls -nd ./* | awk '
    /\// {
      selected = (/^-/ && $5 < 1048576)
      sub(/.*\//, "./")
    }
    selected'
)

但请注意,如果当前目录中有大量文件(当./*shell 扩展时),则该方法将不起作用,这可能会导致达到参数数量的限制。

要包含隐藏文件,-a在这里没有帮助,我们需要告诉 shell 展开它们。 POSIXly,它有点笨拙:

ls -dn ./..?* ./.[!.]* ./*

(这可能会导致有关丢失./..?*./.[!.]*文件的警告消息)。

答案3

由于您只想解析ls's输出,因此您可以找到regular files大小小于上限 ( MAX bytes) 的文件,并且ASSUMING文件名中没有空格/换行符,您可以执行以下操作:

/bin/ls -l | awk -v MAX=150 '/^-/ && $5 <= MAX { print $NF }'

相关内容