简体   繁体   English

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

[英]How can I list files with find and Perl?

I'm working in a HP-UX based machine and I need to list the name of the logs contained in a folder by the date and separated of the name by a ";" 我在基于HP-UX的计算机上工作,我需要按日期列出文件夹中包含的日志名称,并将名称分隔为“;” and the result, sorted by date in descending order this stored in a txt so the content of the txt will be like: 和结果,按日期降序排序,存储在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

I've tried this: 我试过这个:

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

but I can't get what I need, I can't use stats I'm using a for to read line by line so How can I get the date and the path/filename separated by a ; 但我不能让我需要什么,我无法用stats我使用for按行读入行,所以我怎样才能获得日期和path/filename由分离; in a txt, sorted by date descending using bash and eventually perl, thanks! 在一个txt中,按日期降序排序使用bash并最终perl,谢谢!

Can do it all in Perl 可以在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

where you submit the dir-name to the one-liner (or it works with . , the current directory). 你在哪里提交dir-name到一行(或者它与. ,当前目录一起使用)。

Note, I don't see a need for find as you're getting a listing of (log) files from a directory. 注意,我没有看到需要find因为您从目录中获取(日志)文件列表。

This can be optimized, to not run stat repeatedly, but I doubt that it matters in expected use. 这可以优化,不重复运行stat ,但我怀疑它在预期使用中很重要。 I would recommend putting this in a nice little script though. 我建议把它放在一个漂亮的小脚本中。


Still, stat isn't cheap and if this regularly catches long file lists then use 尽管如此, 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

where I've split the statement into yet more lines to emphasize the change. 在那里我将声明分成更多的行以强调变化。

The input file list from glob is used to first build another list, using map , with an arrayref for each filename: The name itself and that file's timestamp. glob的输入文件列表用于首先使用map构建另一个列表,每个文件名都有一个arrayref:名称本身该文件的时间戳。 Then the pair-wise comparisons in sort don't have to run stat every time through; 然后, sort的成对比较不必每次都运行stat ; they use time-stamps precomputed once. 他们使用预先计算过一次的时间戳。 This is called a Schwartzian transform . 这称为Schwartzian变换 Additionally, the sprintf need not run stat again, either. 此外, sprintf也不需要再次运行stat

Note that the optimization comes with an overhead, so use this only when it is indeed expected to be needed. 请注意,优化带来了开销,因此只有在确实需要时才使用它。 See, for example, this post (last section) for a discussion and links. 例如,参见本文 (上一节)的讨论和链接。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM