按大小对从一系列文件夹中检索到的文件进行排序

按大小对从一系列文件夹中检索到的文件进行排序

我检索了 $HOME 目录中的所有 pdf

$ find -E ~ -regex ".*/[^/].*.pdf"

打印1000多个文件;
我打算按大小对它们进行排序并进行搜索

$ stat -f '%z' draft.sh
184

我起草剧本:

#! /usr/local/bin/bash

OLD_IFS=IFS 
IFS=$'\n'

touch sorted_pdf.md

for file in $(find -E ~ -regex ".*/[^/].*.pdf")
do
    file_size=$(stat -c "%s" $file)
    ....

done > sorted_pdf.md

IFS=OLD_IFS

很难让他们一起工作并得到我的结果。您能提供任何提示吗?

我重构了代码

#! /bin/zsh
OLD_IFS=IFS 
IFS=$'\n'

touch sorted_pdf.md

for file in $(find -E ~ -regex ".*/[^/].*.pdf")
do
    # file_size=$(stat -c "%s" $file)
    printf '%s\n' $file(DoL)

done > sorted_pdf.md

IFS=OLD_IFS

但得到错误报告

$ ./sort_files.sh

./sort_files.sh: line 12: syntax error near unexpected token `('
./sort_files.sh: line 12: `    printf '%s\n' $file(DoL)'

答案1

要按大小排序,您可以使用zsh的 glob 限定符(zsh默认安装在 macOS 上,甚至曾经存在sh):

#! /bin/zsh -
printf '%s\n' **/*.pdf(DoL)
  • **/是递归通配符
  • (DoL)是一个 glob 限定符,D用于包含点文件(隐藏文件)findoL按文件长度对生成的列表进行排序L

请注意,这-regex ".*/[^/].*.pdf没有多大意义。

例如匹配 on /home/foo/pdf.*on /home、 then /、 then [^/]on fthen .*on oo、 then .on/和 then pdf

无论-regex有没有-E,您都可以使用-regex '.*\.pdf'来匹配*.pdf文件,但您也可以使用标准的-name '*.pdf'.

你可以使用:

find . -name '*.pdf' -exec stat -f '%z %N' {} + |
  sort -n |
  cut -d ' ' -f 2-

但如果存在带有换行符的文件路径,则这将不起作用。

使用 GNU 实用程序,您可以执行以下操作:

find . -name '*.pdf' -printf '%s %p\0' |
  sort -nz |
  cut -zd ' ' -f 2- |
  tr '\0' '\n'

请注意,如果这些pdf文件中的任何一个是符号链接,则考虑的是符号链接的大小,而不是符号链接目标的大小。要按该目标的大小排序,请将选项更改DoLD-oL或添加-Lstat。对于 GNU find

find -L . \( ! -xtype l -o -prune \) -name '*.pdf' -printf '%s %p\0' |
  sort -nz |
  cut -zd ' ' -f 2- |
  tr '\0' '\n'

对于不区分大小写的匹配,可以替换pdf[pP][dD][fF]或 替换-name-iname(不是标准的,但受 GNU 和 BSD 支持find),或者对于zsh,启用该extendedglob选项并更改pdf(#i)pdf或启用该nocaseglob选项。

答案2

如果您有权访问 GNU findawk

$ find $HOME -iname "*.pdf" -printf '%s\0%p\n' | sort -h -t '\0' | awk -F '\0' '{print $2}'

这个命令:

  • 查找$HOME具有(不区分大小写)pdf 扩展名的所有文件,并打印每个文件的大小和路径;
  • -h使用支持人类可读数字比较的选项按第一个字段对列表进行排序;
  • 打印排序的路径。

相关内容