序列重置时的 Unix 排序

序列重置时的 Unix 排序

我的文件夹中有以下文件列表。每个文件名yyyymmdd_hhmm中都包含日期和时间 ( )。最后 3 个字符是在最大序列之后重置的序列号999,序列将再次从 开始001

node55_20200420_1755_995
node55_20200420_1756_998
node55_20200420_1755_996
node55_20200420_1757_999
node55_20200420_1756_997
node55_20200420_1757_001
node55_20200420_1758_002
node55_20200420_1758_003

当我使用命令时

ls node* | sort

我得到下面的输出。我想要001后面的序列999。除非出现序列重置,否则该命令工作正常。知道如何处理吗?

实际产量

node55_20200420_1755_995
node55_20200420_1755_996
node55_20200420_1756_997
node55_20200420_1756_998
node55_20200420_1757_001
node55_20200420_1757_999
node55_20200420_1758_002
node55_20200420_1758_003

所需输出

node55_20200420_1755_995
node55_20200420_1755_996
node55_20200420_1756_997
node55_20200420_1756_998
node55_20200420_1757_999
node55_20200420_1757_001
node55_20200420_1758_002
node55_20200420_1758_003

答案1

您无法轻松地以一种方式对某些输出进行排序,却以另一种方式进行例外处理。

如果只有999并且000是给定分钟内的序列,您可以尝试将文件名拆分为字段并按降序对最终字段(您的序列计数器)进行排序。但这是行不通的,因为您的示例显示,995并且996也在同一分钟 ( 20200420_1755) 中,并且相同的排序标准也适用于这些标准(即您将得到996995

因此,为了处理这种特定情况,我们使用一些awk.该代码将您的三位数序列号扩展回正确的计数值,按该值排序,然后再次将其剥离

ls node* |
    sort |                                                  # First pass attempt
    awk -F_ '
        BEGIN { OFS = FS }                                  # Delimiter always "_"
        (oseq % 1000) == 999 { thousands++ }                # After previous 999 add 1000
        { seq = $NF + (thousands * 1000) }                  # Convert sequence into value
        seq < oseq && (seq % 1000) < 500 { seq += 1000 }    # Special case
        { $5 = seq; oseq = seq; print }                     # Append counter, output result
    ' |
    sort -t_ -n -k5,6 |                                     # Sort by counter
    cut -d_ -f1-4                                           # Strip it off

使用示例数据集的结果

node55_20200420_1755_995
node55_20200420_1755_996
node55_20200420_1756_997
node55_20200420_1756_998
node55_20200420_1757_999
node55_20200420_1757_001
node55_20200420_1758_002
node55_20200420_1758_003

这段代码并不是万无一失的。如果您确实想在一分钟内生成超过 100 个实例,那么您不应该只使用三位数的序列号。

相关内容