使用bash,如何遍历目录中的所有文件,按创建日期排序,但某些文件名的名称中包含空格

Phi*_*ldo 9 unix bash filenames loops

首先我有

for file in `ls -t dir` ; do
  #blah
done
Run Code Online (Sandbox Code Playgroud)

但是带空格的文件被分成两个迭代.

我已经找到了很多修复空间问题的变种,但随后在$file变量中留下了一些日期信息.

编辑:显示一个这样的变化:

for file in `find . -printf "%T@ %Tc %p\n" | sort -n` ; do
  #blah
done
Run Code Online (Sandbox Code Playgroud)

这个问题是所有时间信息仍然在$file循环中的变量内.(另外,这不起作用,因为我碰巧在OSX上,其实用find程序缺少-printf选项......)

bis*_*hop 5

使用find与组合xargs通过与NUL字节分离文件名,并使用while效率和空间保存读取循环:

find /path/to/dir -type f -print0 | xargs -0 ls -t | while read file
do
    ls "$file" # or whatever you want with $file, which may have spaces
               # so always enclose it in double quotes
done
Run Code Online (Sandbox Code Playgroud)

find生成文件列表,ls在这种情况下按时间排列它们。要颠倒排序顺序,请替换-t-tr。如果要按大小排序,请替换-t-s

例:

$ touch -d '2015-06-17' 'foo foo'
$ touch -d '2016-02-12' 'bar bar'
$ touch -d '2016-05-01' 'baz baz'
$ ls -1
bar bar
baz baz
foo foo
$ find . -type f -print0 | xargs -0 ls -t | while read file
> do
> ls -l "$file"
> done
-rw-rw-r-- 1 bishop bishop 0 May  1 00:00 ./baz baz
-rw-rw-r-- 1 bishop bishop 0 Feb 12 00:00 ./bar bar
-rw-rw-r-- 1 bishop bishop 0 Jun 17  2015 ./foo foo
Run Code Online (Sandbox Code Playgroud)

为了完整起见,我将强调一个从评论到问题的观点:-t是按修改时间排序,而不是严格按照创建时间排序。这些文件所在的文件系统决定了创建时间是否可用。由于您最初的尝试是使用-t,所以我认为修改时间就是您所关心的,即使这并不是很真实。

如果需要创建时间,则必须将其从某个来源中拉出来,例如,stat或者将文件名编码在此处。从根本上讲,这意味着用xargs -0 ls -t管道输送到的合适命令来代替sort,例如:xargs -0 stat -c '%W' | sort -n