如何使用find和Perl列出文件?

时间:2019-02-11 20:46:19

标签: bash file perl directory-listing

我正在基于HP-UX的计算机上工作,我需要按日期列出文件夹中包含的日志名称,并用“;”分隔名称。结果以降序按日期排序,结果存储在txt中,因此txt的内容将类似于:

2019-02-02;/home/user/Documents/imthelog03.log
2019-02-01;/home/user/Documents/imthelog02.log
2019-01-29;/home/user/Documents/imthelog01.log

我已经尝试过了:

find /home/user/Documents/*.log* exec perl -MPOSIX -e 'print POSIX::strftime "%Y%m%d\n", localtime((stat $ARGV[0])[9])'

但是我无法获得所需的东西,我无法使用stats 我正在使用for逐行读取 因此,如何获取日期和path/filename并以txt中的;分隔,按日期排序,使用bash降序排列,最后使用perl,谢谢!

2 个答案:

答案 0 :(得分:5)

可以在Perl中完成所有操作

perl -MPOSIX=strftime -wE'$d = shift || "."; 
    say strftime("%Y-%m-%d", localtime((stat $_)[9])), "; $_" 
        for sort { (stat $b)[9] <=> (stat $a)[9] } glob "$d/*log*"
' dir-name

dir-name提交到单行代码(或它与当前目录.一起使用)。

注意,由于您正在从目录中获取(日志)文件列表,因此我认为不需要find

可以对其进行优化,以免重复运行stat,但是我怀疑这对预期用途是否有意义。我建议将其放在一个不错的小脚本中。


不过,stat并不便宜,如果它经常捕获长文件列表,则使用

perl -MPOSIX=strftime -wE'$d = shift || "."; 
    say strftime("%Y-%m-%d", localtime($_->[1])), "; $_->[0]" 
        for 
            sort { $b->[1] <=> $a->[1] } 
                map { [$_, (stat $_)[9]] } glob "$d/*log*"
' dir-name

我在其中将语句分成更多行以强调更改。

使用glob首先使用map的输入文件列表构建另一个列表,并为每个文件名使用arrayref:名称本身。这样,sort中的成对比较就不必每次都运行stat了;他们使用预先计算一次的时间戳。这称为Schwartzian transform。此外,sprintf也无需再次运行stat

请注意,优化带有开销,因此仅在确实需要时才使用此开销。例如,请参见this post(最后一部分)以获取讨论和链接。

答案 1 :(得分:0)

find /home/user/Documents/*.log* -type f -exec perl -MPOSIX -le 'print strftime("%Y%m%d",localtime((stat $ARGV[0])[9])),";$ARGV[0]"' {} \; | sort -k1,1