解析 ls
的输出以遍历文件列表是 bad .那么我应该如何按照文件的首次创建顺序遍历文件列表呢?我在这里浏览了几个关于 SO 的问题,它们似乎都在解析 ls
。
嵌入式链接建议:
Things get more difficult if you wanted some specific sorting that only
ls
can do, such as ordering bymtime
. If you want the oldest or newest file in a directory, don't usels -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;
除了 sort
和 stat
之外,所有命令都是实际的原生 Bash 命令(内置)*。如果你真的想要,你可以implement your own sort
using Bash builtins only ,但我看不到摆脱 stat
的方法。
重要的部分是read -d $'\0'
、printf '%s\0'
和sort -z
。所有这些命令都与它们的空分隔符选项一起使用,这意味着可以安全地处理任何文件名。此外,在 "$file"
和 "${anarray[*]}"
中使用双引号是必不可少的。
*许多人认为 GNU 工具在某种程度上是 Bash 的一部分,但从技术上讲它们不是。因此,stat
和 sort
与 perl
一样是非原生的。
关于bash - 按照在 bash 中创建的顺序遍历文件名列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25577074/