按大小对文件名变量列表进行排序

按大小对文件名变量列表进行排序

我正在尝试创建一个小脚本,它将获取文件名,然后按大小对该列表进行排序,并对该列表执行命令。到目前为止我有:

#!/bin/bash
filenames="one \
           two \
           three"
for i in $filenames; do
...
done

它有效,但我想在点击 for 命令之前按文件大小对列表进行排序。

答案1

如果您的文件名不包含任何换行符并且您的系统具有 GNU stat,您可以:

  • 使用数组变量filenames
  • 用于stat打印每个文件的大小和文件名,然后使用sort结果(反向数字),然后删除第一个字段(大小)以cut获取按大小排序的文件名(最大的在前)。
  • 将结果送入while循环以进行进一步处理。

filenames=( one two three )
while IFS= read -r file; do
  echo "do something with $file"
done < <(stat --printf '%s\t%n\n' -- "${filenames[@]}" | sort -nr | cut -f2-)

与上面相同,但使用空字符作为分隔符(如果你不能保证你的文件名不包含换行符;你还需要 GNUsort和 GNU cut):

filenames=( one two three )
while IFS= read -r -d $'\0' file; do
  printf 'do something with %s\n' "$file"
done < <(stat --printf '%s\t%n\0' -- "${filenames[@]}" | sort -znr | cut -zf2-)

请注意,对于类型的文件名符号链接,所考虑的是链接本身的大小(而不是它指向的文件的大小)。添加-L选项来stat更改它。

请注意,它不适用于名为 as 的文件-stat将其解释为在标准输入上打开的文件。使用./-来解决它。

答案2

zsh,方法相同这是关于按 mtime 排序的类似问题的答案,本身改编自那个,根据任意顺序对数组进行排序(有关详细信息,请参阅后一个):

zmodload zsh/stat

array=(one two three...)

# store sizes in an "A"ssociative array:
typeset -A size
stat -nL -A size +size -- $array

# sort using the oe glob qualifier "n"umerically
sorted_array=(/(e['reply=($array)']noe['REPLY=$size[$REPLY]'])

相关内容