Bash

按從一系列文件夾中檢索到的大小對文件進行排序

  • November 24, 2018

我檢索了 $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)'

要按大小排序,您可以使用zsh’s 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 /and then pdf

With -regex, with or without -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或添加到. 使用 GNU :-L``stat``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),或者 for zsh,啟用該extendedglob選項並更改pdf(#i)pdf或啟用該nocaseglob選項。

引用自:https://unix.stackexchange.com/questions/477983