我检索了 $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
用于包含点文件(隐藏文件)find
,oL
按文件长度对生成的列表进行排序L
。
请注意,这-regex ".*/[^/].*.pdf
没有多大意义。
例如匹配 on /home/foo/pdf
、.*
on /home
、 then /
、 then [^/]
on f
then .*
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
文件中的任何一个是符号链接,则考虑的是符号链接的大小,而不是符号链接目标的大小。要按该目标的大小排序,请将选项更改DoL
为D-oL
或添加-L
到stat
。对于 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 find
,awk
:
$ find $HOME -iname "*.pdf" -printf '%s\0%p\n' | sort -h -t '\0' | awk -F '\0' '{print $2}'
这个命令:
- 查找
$HOME
具有(不区分大小写)pdf 扩展名的所有文件,并打印每个文件的大小和路径; -h
使用支持人类可读数字比较的选项按第一个字段对列表进行排序;- 打印排序的路径。