按时间戳顺序查找文件

按时间戳顺序查找文件

dir有两个常规文件。

file1abc\nfile2def\n。用gzip压缩这两个文件,如下图,

#ls
#echo 'abc\n' > file1
#echo 'def\n' > file2
#gzip file1
#gzip file2
#ls
file1.gz  file2.gz

在我抓取内容后,

#find . -type f  -name "*.gz" -exec zgrep -Iq . \{} \; -exec zcat \{} \;
def\n
abc\n

我没有按照文件创建时间的顺序获取文件的内容。预期输出应始终为abc\ndef\n.

有趣的观察:实际输出有时,def\nabc\n有时abc\ndef\n

问题:

如何按时间戳顺序(递减/递增)查找文件?

答案1

报告的文件顺序find对用户来说是不透明的。它可以是它们在目录中出现的顺序。一些find实现通过 inode 编号或其他标准对它们进行重新排序,以尝试提高性能。改变顺序的唯一方法是通过-depth谓词告诉find处理/输出在它们所在的分支之前离开。

作为 的替代方案find,您可以使用zsh的递归 glob 功能:

zgrep whatever ./**/*.gz(D.Om)

globOm限定符按最后修改时间排序(最旧的在前)。.仅适用于常规文件(相当于find's -type f),D包括find默认情况下隐藏的(点)文件。

如果你得到一个arg 列表太长错误,您可以使用zargs

autoload -U zargs # best in ~/.zshrc
zargs ./**/*.gz(D.Om) -- zgrep whatever

使用bash(或任何支持 Ksh 样式进程替换的 shell)和最新的 GNU 工具,等效项将是:

xargs -r0a <(
  export LC_ALL=C
  find . -type f -name '*.gz' -printf '%T@\t%p\0' |
    sort -zn | cut -zf2-) zgrep whatever

答案2

一种选择是输出文件时间戳以及文件路径,按其排序,然后将其删除:

find -type f -name "*.gz" -printf '%C@\t%p\n'|sort -nk1|cut -f2-|xargs zcat 

请注意,如果您的文件名可能包含潜在不安全的字符(例如空格),只需替换

xargs zcat 

xargs -d "\n" zcat 

如果您需要适应文件名中的换行符,则可以使用空字节来终止记录,如 @stéphane-chazelas 答案中详细说明(通过这在实践中很少会出现问题)。

答案3

不幸的是,find 命令的工作方式不能保证输出按字母顺序或文件年龄时间顺序排列。你可以尝试这样的事情:

ls -1dtr $(find . -maxdepth 1 -type f -name '*.gz') | xargs gzcat $1

相关内容