perl - 从包含日期的文件中排序并提取一定数量的行

我有一个 txt 文件,日期如下:

yyyymmdd

原始数据是这样的:

20171115
20171115
20180903
...
20201231

它们超过 10 万行。我试图将“最新”的 10k 行保存在一个文件中,并将 10k“最旧”的 10k 行保存在一个单独的文件中。

我想这一定是一个两步过程:

  1. 排序行,

  2. 然后提取顶部的 10k 行,“最新 = 最近日期”和接近文件末尾的 10k 行,即“最旧 = 最古老的日期”

我如何使用 awk 实现它?

虽然我什至尝试过使用 perl 但没有成功,所以 perl one liner 也会被高度接受。

编辑:我更喜欢一个干净聪明的解决方案,以便我从中学习, 而不是我尝试的优化。

perl 示例

@dates = ('20170401', '20170721', '20200911');
@ordered = sort { &compare } @dates;
sub compare {
    $a =~ /(\d{4})(\d{2})(\d{2})/;
    $c = $3 . $2 . $1;
    $b =~ /(\d{4})(\d{2})(\d{2})/;
    $c = $3 . $2 . $1;
    $c <=> $d;
}
print "@ordered\n";

最佳答案

这是一个使用 perl 的答案. 如果您希望最早的排在最前面,您可以使用标准排序顺序:

@dates = sort @dates;

反向排序,最新的在最上面:

@dates = sort { $b <=> $a } @dates;
#                  ^^^
#                   |
# numerical three-way comparison returning -1, 0 or +1

然后您可以从顶部提取 10000 个条目:

my $keep = 10000;
my @top = splice @dates, 0, $keep;

从底部开始 10000:

$keep = @dates unless(@dates >= $keep);
my @bottom = splice @dates, -$keep;

@dates 现在将包含您提取的顶部 10000 和底部 10000 之间的日期。

如果需要,您可以将这两个数组保存到文件中:

sub save {
    my $filename=shift;
    open my $fh, '>', $filename or die "$filename: $!";
    print $fh join("\n", @_) . "\n" if(@_);
    close $fh;
}

save('top', @top);
save('bottom', @bottom);

https://stackoverflow.com/questions/69978477/

相关文章:

reactjs - 如何将参数传递给从自定义 Hook 转换的函数?

awk - 使用 grep 或 awk 查找 txt 和 csv 文件之间的匹配行

python - AttributeError : module 'cv2.cv2' has no

r - R中多列的值计数

asp.net-core - 安装 .NET 6 后无法创建 EF 迁移

bash - 组合两个 grep 命令来处理来自文件的输入,或者 grep 行以一个特定的子字符串开

javascript - 带有 Material-UI 的 SSR 上的@emotion/cache

python - 遍历列表并从头开始重新启动

python - 算法题: Finding the cheapest flight

haskell - 如何使用 `zipTree` 实现 `foldTree` ?