マルチレベルファイル名/パスのサブストリングに基づいてファイル名リスト(txtファイル)をソートする方法。特別な課題:2種類のファイル名規則

マルチレベルファイル名/パスのサブストリングに基づいてファイル名リスト(txtファイル)をソートする方法。特別な課題:2種類のファイル名規則

次のファイル名/パスのリストを並べ替えたいと思います。

L1_Data/level1/192027/LC08_L1TP_192027_20201126_20210316_01_T1 DONE
L1_Data/level1/192028/LC08_L1TP_192028_20201126_20210316_01_T1 DONE
L1_Data/level1/192029/LC08_L1TP_192029_20201126_20210316_01_T1 DONE
L1_Data/level1/191027/LE07_L1TP_191027_20201127_20201223_01_T1 DONE
L1_Data/level1/191029/LE07_L1TP_191029_20201127_20201223_01_T1 DONE
L1_Data/level1/192027/LC08_L1TP_192027_20201212_20210313_01_T1 QUEUED
L1_Data/level1/191028/LE07_L1TP_191028_20201213_20210108_01_T1 DONE
L1_Data/level1/191029/LE07_L1TP_191029_20201213_20210108_01_T1 DONE
L1_Data/level1/191027/LC08_L1TP_191027_20201221_20210310_01_T1 DONE
L1_Data/level1/T32TQS/S2B_MSIL1C_20200101T100319_N0208_R122_T32TQS_20200101T110654.SAFE DONE
L1_Data/level1/T32TQR/S2B_MSIL1C_20200101T100319_N0208_R122_T32TQR_20200101T110654.SAFE QUEUED
L1_Data/level1/T33TUL/S2B_MSIL1C_20200101T100319_N0208_R122_T33TUL_20200101T110654.SAFE DONE
L1_Data/level1/T33TUM/S2B_MSIL1C_20200101T100319_N0208_R122_T33TUM_20200101T110654.SAFE DONE
L1_Data/level1/T32TQS/S2A_MSIL1C_20200102T102421_N0208_R065_T32TQS_20200102T105534.SAFE DONE
L1_Data/level1/T33TUL/S2B_MSIL1C_20200104T101319_N0208_R022_T33TUL_20200104T121239.SAFE DONE
L1_Data/level1/T32TQR/S2B_MSIL1C_20200104T101319_N0208_R022_T32TQR_20200104T121239.SAFE QUEUED
L1_Data/level1/T32TQS/S2A_MSIL1C_20200106T100401_N0208_R122_T32TQS_20200106T103423.SAFE DONE

各行には、ファイル名(パスを含む)と対応するジョブ状態(待機中/完了)が含まれています。各ファイル名には、衛星タイプ、録画日、フットプリントなどの衛星映像データに関する情報が含まれる。

それでは、次の優先順位に従ってリストを並べ替えたいと思います。

  1. 勤務状況 ->すでにキューにあります。最初。段階的にこれは私にとって問題ではありませんが、後続のステップの解決策はこれらの組み合わせで構成されています(次の画像の後に私の問題の詳細な説明を見つけることができます)。
  2. 衛星タイプ(S2A=Sentinel A; S2B=Sentinel B; LC08=Landsat 8; LE07=Landsat 7) -->S2A/B(AまたはB)で始まり、LC08、LE07を順番に選択します。つまり、Sentinel 2、Landsat 8、Landsat 7を区別したいと思います。しかし、センチネル2Aとセンチネル2Bの間。
  3. 記録日、昇順
  4. 足跡、上昇

下の画像は、対応する部分文字列の位置と私の問題の説明を示しています。

ここに画像の説明を入力してください。

非常に基本的な知識だけを持っている以外タイプコマンド、私の具体的な質問は次のとおりです。

  • a) 部分文字列を正しく処理します。
  • b)2つの異なるファイル名タイプ(/ convention)、
  • c)何よりも、Sentinelファイル名に5つのアンダースコア、6つのLandsatファイル名があり、2つのサブストリング順序が異なるため、アンダースコアを区切り文字として使用することはできません。
  • d) 注文S2A/B今後LC08今後LE07残念ながらアルファベット順ではありませんが、
  • e) 解決するS2AそしてS2B衛星全体。もちろん、この問題は次のように解決できます。S2ただし、2 文字のみで構成されるため、ファイル名の完全な文字列の他の部分と混同される危険性があります。 (実際にはリストははるかに長く、頻繁に更新されるため、「false」を含めることができます。S2他のラインまたは今後のラインにあります)。

最後に並べ替えられたリストは次のようになります。

L1_Data/level1/T32TQR/S2B_MSIL1C_20200101T100319_N0208_R122_T32TQR_20200101T110654.SAFE QUEUED
L1_Data/level1/T32TQR/S2B_MSIL1C_20200104T101319_N0208_R022_T32TQR_20200104T121239.SAFE QUEUED
L1_Data/level1/192027/LC08_L1TP_192027_20201212_20210313_01_T1 QUEUED
L1_Data/level1/T32TQS/S2B_MSIL1C_20200101T100319_N0208_R122_T32TQS_20200101T110654.SAFE DONE
L1_Data/level1/T33TUL/S2B_MSIL1C_20200101T100319_N0208_R122_T33TUL_20200101T110654.SAFE DONE
L1_Data/level1/T33TUM/S2B_MSIL1C_20200101T100319_N0208_R122_T33TUM_20200101T110654.SAFE DONE
L1_Data/level1/T32TQS/S2A_MSIL1C_20200102T102421_N0208_R065_T32TQS_20200102T105534.SAFE DONE
L1_Data/level1/T33TUL/S2B_MSIL1C_20200104T101319_N0208_R022_T33TUL_20200104T121239.SAFE DONE
L1_Data/level1/T32TQS/S2A_MSIL1C_20200106T100401_N0208_R122_T32TQS_20200106T103423.SAFE DONE
L1_Data/level1/192027/LC08_L1TP_192027_20201126_20210316_01_T1 DONE
L1_Data/level1/192028/LC08_L1TP_192028_20201126_20210316_01_T1 DONE
L1_Data/level1/192029/LC08_L1TP_192029_20201126_20210316_01_T1 DONE
L1_Data/level1/191028/LE07_L1TP_191028_20201213_20210108_01_T1 DONE
L1_Data/level1/191029/LE07_L1TP_191029_20201213_20210108_01_T1 DONE
L1_Data/level1/191027/LE07_L1TP_191027_20201127_20201223_01_T1 DONE
L1_Data/level1/191029/LE07_L1TP_191029_20201127_20201223_01_T1 DONE

誰でも私を助けることができますか?

ベストアンサー1

問題は、ソートフィールドが行の同じ列にないことです。

私は柔軟性を最大化するためにPerlを使用しています。これは「custom_sort.pl」です。

#! perl

while (<>) {
    # capture the fields of an "L" satellite
    if (/.*\/(L...)_.*?_(\d+)_(\d+)\S+\s+(.*)/) {
        push @data, [$_, $4, $1, $3, $2]
    }
    # capture the fields of an "S" satellite
    elsif (/.*\/(S..)_.*?_(\d{8}).*?_.*?_.*?_(.*?)_\S+\s+(.*)/) {
        push @data, [$_, $4, $1, $2, $3]
    }
}

sub mysort {
    -($a->[1] cmp $b->[1])              # work status, descending
    || cmp_satellite($a->[2], $b->[2])  # satellite
    || $a->[3] <=> $b->[3]              # record date
    || $a->[4] cmp $b->[4]              # footprint
}
sub cmp_satellite {
    my ($a, $b) = @_;
    return -1 if $a =~ /^S/;
    return +1 if $b =~ /^S/;
    $a cmp $b
}

print $_->[0] for sort mysort @data

実行する

perl custom_sort.pl file

おすすめ記事