bash - 按照在 bash 中创建的顺序遍历文件名列表

标签 bash

解析 ls 的输出以遍历文件列表是 bad .那么我应该如何按照文件的首次创建顺序遍历文件列表呢?我在这里浏览了几个关于 SO 的问题,它们似乎都在解析 ls

嵌入式链接建议:

Things get more difficult if you wanted some specific sorting that only ls can do, such as ordering by mtime. If you want the oldest or newest file in a directory, don't use ls -t | head -1 -- read Bash FAQ 99 instead. If you truly need a list of all the files in a directory in order by mtime so that you can process them in sequence, switch to perl, and have your perl program do its own directory opening and sorting. Then do the processing in the perl program, or -- worst case scenario -- have the perl program spit out the filenames with NUL delimiters.

Even better, put the modification time in the filename, in YYYYMMDD format, so that glob order is also mtime order. Then you don't need ls or perl or anything. (The vast majority of cases where people want the oldest or newest file in a directory can be solved just by doing this.)

这是否意味着在 bash没有本地方式来做这件事?我无权修改文件名以在其中包含时间。我需要在 cron 中安排一个每 5 分钟运行一次的脚本,生成一个包含特定目录中按创建时间排序的所有文件的数组,并对文件名执行一些操作并将它们移动到另一个地点。

下面的工作但只是因为我没有有趣的文件名。这些文件是由服务器创建的,因此它永远不会有特殊字符、空格、换行符等。

files=( $(ls -1tr) ) 

我可以编写一个 perl 脚本来满足我的需要,但如果有人可以建议在 bash 中执行此操作的正确方法,我将不胜感激。可移植选项会很棒,但使用最新 GNU 实用程序的解决方案也不会成为问题。

最佳答案

sorthelper=();
for file in *; do
    # We need something that can easily be sorted.
    # Here, we use "<date><filename>".
    # Note that this works with any special characters in filenames

    sorthelper+=("$(stat -n -f "%Sm%N" -t "%Y%m%d%H%M%S" -- "$file")"); # Mac OS X only
    # or
    sorthelper+=("$(stat --printf "%Y    %n" -- "$file")"); # Linux only
done;

sorted=();
while read -d $'\0' elem; do
    # this strips away the first 14 characters (<date>) 
    sorted+=("${elem:14}");
done < <(printf '%s\0' "${sorthelper[@]}" | sort -z)

for file in "${sorted[@]}"; do
    # do your stuff...
    echo "$file";
done;

除了 sortstat 之外,所有命令都是实际的原生 Bash 命令(内置)*。如果你真的想要,你可以implement your own sort using Bash builtins only ,但我看不到摆脱 stat 的方法。

重要的部分是read -d $'\0'printf '%s\0'sort -z。所有这些命令都与它们的空分隔符选项一起使用,这意味着可以安全地处理任何文件名。此外,在 "$file""${anarray[*]}" 中使用双引号是必不可少的。

*许多人认为 GNU 工具在某种程度上是 Bash 的一部分,但从技术上讲它们不是。因此,statsortperl 一样是非原生的。

关于bash - 按照在 bash 中创建的顺序遍历文件名列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25577074/

相关文章:

bash - 如何找到目录树中的所有符号链接(symbolic link)?

linux - AWK编程,条件语句

linux - rpm --test 从不返回非空字符串?

linux - 从单个字符中查找单词

r - 如何从 R 中运行多命令 Linux shell 脚本?

bash - 如何在没有 stdbuf 和类似工具的情况下取消缓冲遗留运行二进制文件的标准输出

java - 构建统一的config.properties。如果 Java 中的一个属性文件中有多个具有相同键的属性怎么办?

linux - 如何获取特定格式的时间 - Linux

linux - Bash 脚本(Linux)

linux - 在 bash 脚本中传递标志失败