首页 > 解决方案 > 基于时间字符串名称的bash排序数组

问题描述

我在目录中有文件列表,其中文件名的时间格式为 hh-mm-ss。

05-31-04.mp4 
05-32-04.mp4 
05-34-04.mp4 
05-33-04.mp4
05-30-00.mp4

我需要根据文件名对文件进行排序

喜欢

05-30-00.mp4
05-31-04.mp4 
05-32-04.mp4 
05-33-04.mp4
05-34-04.mp4 

现在我有以下代码来列出文件

x=$(find . -name "*.mp4" -printf "%f\n")
for file in $x; do
  echo "File -> $file"

标签: bashshell

解决方案


这根本不是一个数组。 x是一个简单的字符串变量,在不引用它的情况下循环它会将其拆分为空格。

如果您的文件名中包含空格或其他 shell 元字符,那将是有问题的,但如果您的简单文件名具有代表性,那就没有意义了。在那种情况下,只是sort......

x=$(find . -name "*.mp4" -printf "%f\n" | sort)
printf "File -> %s\n" $x

但是,不引用您的字符串变量会带来大量警告。可能实际上确实使用了一个数组。

readarray -d '' x < <(find . -name "*.mp4" -print0 | sort -z)
printf "File -> %s\n" "${x[@]}"

readarray需要 Bash 4+,因此无法在 MacOS 上开箱即用。find -print0它的伴侣sort -z是 GNU 扩展,不能移植到 POSIX / 非 GNU 系统。)

如果所有文件都在当前目录中,find则完全大材小用;只需使用 shell 的内置通配符扩展,默认排序。

printf "File -> %s\n" *.mp4

如果您需要遍历文件并做一些比仅打印每个文件更有用的事情,则不需要变量。只需直接循环通配符扩展即可。

for file in *.mp4; do
    # This is where we do something more useful than ...
    printf "File -> %s\n" "$file"
done

请注意您还需要如何"$file"在循环内引用。当您使用琐碎的文件名对其进行测试时,它看起来就像在不引用的情况下工作,但是当您在真实文件上运行它时,它会以壮观且难以调试的方式中断。


推荐阅读