从目录中检索最新数据

从目录中检索最新数据

我想从此data.list目录中检索行数:Project/chris/company/Delta/force/run_20210619_df/total/data.list但问题是run_20210619_df更改,并且每次将新数据更新到 data.list 时都会被替换。

可以说原始目录是:

Project/chris/company/Delta/force/run_20210619_df/total/data.list

但今天data.list正在更新,因此在仍然存在的情况下形成了一个新目录run_20210619_dfProject/chris/company/Delta/force/run_20210624_df/total/data.list

并且两个目录都包含data.list

我可以制作一个始终可以读取的脚本吗最新版本 data.list?在这种情况下它的内部run_20210624_df

我从这个开始:

use strict;
use warnings;
use feature 'say';

use Data::Dumper;

my $files = './Project/chris/company/Delta/force/*/total/data.list';
my $hashref;

for my $file ( glob($files) ) {
    my($date) = (split('/',$_))[6];
    if( $hashref->{$id) and $date gt $hashref->{$id}{date} ) {
        $hashref->{$id}{file}   = $file;
        $hashref->{$id}{date}   = $date;
        $hashref->{$id}{count}  = count_lines($file);
    } else {
        $hashref->{$id}{file}   = $file;
        $hashref->{$id}{date}   = $date;
        $hashref->{$id}{count}  = count_lines($file);
    }
}

say Dumper($hashref);

sub count_lines {
    my $fname = shift;
    my $count;

    open my $fh, '<', $fname or die $!;
    $count++ while <$fh>;
    close $fh;

    return $count;
}

不幸的是,当我运行脚本时,它无法检测到要从中提取信息的 data.list 。因此打印 3 次,因为我有 3 个不同的 $date 文件

答案1

使用该函数按每个文件的修改时间戳对 glob 进行排序stat

例如

代替:

for my $file ( glob($files) ) {

使用:

for my $file ( sort { (stat $b)[9] <=> (stat $a)[9] } glob($files) ) {

这将以相反的时间戳顺序排序,即第一个元素将是最新的。

您可能不想迭代与 glob 匹配的整个文件列表,只需使用最新的一个:

#!/usr/bin/perl

use strict;
use warnings;
use feature 'say';

my $glob_pattern = './Project/chris/company/Delta/force/*/total/data.list';

my @files = ( sort { (stat $b)[9] <=> (stat $a)[9] } glob($glob_pattern) );
my $file = $files[0];

printf "%s: %i\n", $file, count_lines($file);

sub count_lines {
...
...
...
}

为什么(stat $b)[9](stat $a)[9]?因为修改时间是函数返回的13个元素列表中的第9号元素stat。它的常用用法如下:

my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
    $atime,$mtime,$ctime,$blksize,$blocks) = stat($filename);

atimemtime、 都是ctime数值,自纪元(格林尼治标准时间 1970 年 1 月 1 日午夜)以来的秒数 - 即标准 unix time_t 值。因为它们是数字,所以可以像任何其他数字值一样对它们进行排序、比较、加法、减法等。

perldoc -f stat有关 stat 函数的更多详细信息,请参阅 参考资料。

另请参阅perldoc -f sort有关该sort功能的详细信息。在上面的代码中,它使用代码块按从文件名派生的值(即它们的 mtimes)进行排序,而不是按文件名本身进行排序。

顺便说一句,请记住 perl 数组从 0 开始,而不是 1。因此 [9] 是第十个元素,从 0 开始。另外, [6] 是第七个元素,所以你(split('/',$_))[6]可能应该[5]代替[6]。现在不需要,因为上面的代码使用文件的实际时间戳。

答案2

zsh

wc -l < ./Project/chris/company/Delta/force/run_<->_df/total/data.list([-1])

data.list将给出编号最高的行数run_..._df。尽管

wc -l < ./Project/chris/company/Delta/force/run_<->_df/total/data.list(-om[1])

将给出最近修改的行数data.list

或者以数字方式对路径中找到的第一个数字序列进行O排序:n

wc -l < ./Project/chris/company/Delta/force/*/total/data.list(nOe['
  REPLY=${(MS)REPLY##<->}'][1])

1 从技术上讲,换行符,如果最后一个“行”没有分隔,这可能会给你一个与 perl 方法不同的数字。

相关内容