다중 레벨 파일 이름/경로의 하위 문자열을 기준으로 파일 이름 목록(txt 파일)을 정렬하는 방법. 특별 과제: 두 가지 유형의 파일 이름 규칙

다중 레벨 파일 이름/경로의 하위 문자열을 기준으로 파일 이름 목록(txt 파일)을 정렬하는 방법. 특별 과제: 두 가지 유형의 파일 이름 규칙

다음 파일 이름/경로 목록을 정렬하고 싶습니다.

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) 두 가지 다른 파일 이름 유형(/convention),
  • c) 무엇보다도 Sentinel 파일 이름에 밑줄이 5개, Landsat 파일 이름에 6개가 있고 하위 문자열 순서가 둘 사이에 다르기 때문에 밑줄을 구분 기호로 사용할 수 없습니다.
  • d) 주문S2A/B앞으로LC08앞으로LE07아쉽게도 알파벳 순서는 아니지만,
  • e) 해결하다S2A그리고S2B위성 전체. 물론 이 문제는 다음과 같이 해결될 수 있습니다.S2그러나 두 문자로만 구성되므로 전체 파일 이름 문자열의 다른 부분과 혼동될 위험이 있습니다. (실제로 목록은 훨씬 길고 수시로 업데이트되므로 "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

답변2

awk, sortcut:을 사용하십시오 .

awk -F'[/ ]' -v OFS='\t' '
{
  status=$NF # this is the last field

  split($(NF-1), parts, "_") # split filename into array `parts`

  if (parts[1]=="S2A" || parts[1]=="S2B") type=1
  else if (parts[1]=="LC08"){ type=2 }
  else if (parts[1]=="LE07"){ type=3 }
  else { print "error, got unknown type " parts[1]; exit 1 }

  date=(type==1 ? substr(parts[3], 1, 8) : parts[4])
  footprint=(type==1 ? parts[6] : parts[3])
  
  print status, type, date, footprint, $0
}
' file | sort -k1,1r -k2,2n -k3,3 -k4,4 | cut -f5-

아이디어는 각 기록에서 작업 상태, 위성 유형, 녹화 날짜 및 공간을 추출하고 이를 4개의 변수에 저장하고 유형을 숫자로 대체하여 사용자 정의 순서를 정의하는 것입니다.

그런 다음 4개의 변수(원본 레코드로 구분되고 접미사가 붙은 탭)를 인쇄하고 필요에 따라 출력을 정렬한 다음 를 사용하여 처음 4개의 필드를 제거합니다 cut.

산출:

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/191027/LC08_L1TP_191027_20201221_20210310_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/191028/LE07_L1TP_191028_20201213_20210108_01_T1 DONE
L1_Data/level1/191029/LE07_L1TP_191029_20201213_20210108_01_T1 DONE

관련 정보