Сортировка файлов Linux на основе подмножества данных

#linux #sorting

#linux #сортировка

Вопрос:

ОПЕРАЦИОННАЯ система — Red Hat Enterprise Linux 8.2 (Ootpa)

Ниже приведен мой плоский файл.

 G010XX   OLTP    PDOA210105210304210105000000000000000000000000F                        
G2019998199916        86010027472                       XXXLXXSEXXX860  XXUPMU TEST     
G2019998199916        86010027472                       XXXLXXSEXXX860  XXUPMU TEST     
G2019998199916        86010027472                       XXXLXXSEXXX860  XXUPMU TEST     
G2019998199916        86010027524                       XXXLXXSEXXX860  XXUPMU TEST     
G2019998199916        86010027524                       XXXLXXSEXXX860  XXUPMU TEST     
G2019998199916        86010027524                       XXXLXXSEXXX860  XXUPMU TEST     
G2029998199916        86010027472                       XXXLXXSEXXXXXW-00000000000000000
G2029998199916        86010027472                       XXXLXXSEXXXXXW-00000000000000001
G2029998199916        86010027472                       XXXLXXSEXXXXXW000000000039213488
G2029998199916        86010027524                       XXXLXXSEXXXXXW000000000000000000
G2029998199916        86010027524                       XXXLXXSEXXXXXW000000000000000002
G2029998199916        86010027524                       XXXLXXSEXXXXXW000000000000099357
G2039998199916        86010027472                       XXXLXXSEXXXXXW201210201210095900
G2039998199916        86010027472                       XXXLXXSEXXXXXW201210201210110141
G2039998199916        86010027472                       XXXLXXSEXXXXXW201210201210141946
G2039998199916        86010027524                       XXXLXXSEXXXXXW201210201210163210
G2039998199916        86010027524                       XXXLXXSEXXXXXW201211201211141445
G2039998199916        86010027524                       XXXLXXSEXXXXXW201211201211144629
G2049998199916        86010027472                       XXXLXXSEXXXXXW201210201210095900
G2049998199916        86010027472                       XXXLXXSEXXXXXW201210201210110141
G2049998199916        86010027472                       XXXLXXSEXXXXXW201210201210141946
G2049998199916        86010027524                       XXXLXXSEXXXXXW201210201210163210
G2049998199916        86010027524                       XXXLXXSEXXXXXW201211201211141445
G2049998199916        86010027524                       XXXLXXSEXXXXXW201211201211144629
G020000011140000000000000000000000.000                                                  
 
  1. Позиция 1-4 — тип записи
  2. Позиция 23-54 — номер учетной записи
  3. Позиция 71-88 сведения о дате транзакции (только для записей типа G203 и G204)

Мое требование заключается в

  1. Устранение дубликатов в записях G201 и G202 на основе номера учетной записи
  2. Выполните сортировку следующим образом Уровень 1 — Сортировка по номеру счета Уровень 2 — Сортировка по типу записи Уровень 2 — Сортировка по дате транзакции (доступно только в G203 и G204)

Ожидаемый результат

 G010XX   OLTP    PDOA210105210304210105000000000000000000000000F                        
G2019998199916        86010027472                       XXXLXXSEXXX860  XXUPMU TEST     
G2029998199916        86010027472                       XXXLXXSEXXXXXW-00000000000000000
G2039998199916        86010027472                       XXXLXXSEXXXXXW201210201210095900
G2049998199916        86010027472                       XXXLXXSEXXXXXW201210201210095900
G2039998199916        86010027472                       XXXLXXSEXXXXXW201210201210110141
G2049998199916        86010027472                       XXXLXXSEXXXXXW201210201210110141
G2039998199916        86010027472                       XXXLXXSEXXXXXW201210201210141946
G2049998199916        86010027472                       XXXLXXSEXXXXXW201210201210141946
G2019998199916        86010027524                       XXXLXXSEXXX860  XXUPMU TEST     
G2029998199916        86010027524                       XXXLXXSEXXXXXW000000000000000000
G2039998199916        86010027524                       XXXLXXSEXXXXXW201210201210163210
G2049998199916        86010027524                       XXXLXXSEXXXXXW201210201210163210
G2039998199916        86010027524                       XXXLXXSEXXXXXW201211201211141445
G2049998199916        86010027524                       XXXLXXSEXXXXXW201211201211141445
G2039998199916        86010027524                       XXXLXXSEXXXXXW201211201211144629
G2049998199916        86010027524                       XXXLXXSEXXXXXW201211201211144629
G020000011140000000000000000000000.000                                                  
 

Я попробовал два подхода. Но не получение желаемого результата. oa — это мое имя файла.

 [tmp] $ (
> grep "^G010" oa amp;amp; 
> ( 
> grep "^G201" oa|sort -u -k 1.1,1.4 -k 1.23,1.56 amp;amp; 
> grep "^G202" oa|sort -u -k 1.1,1.4 -k 1.23,1.56 amp;amp; 
> grep -E "^(G203|G204|G205|G206)" oa | sort -k 1.23,1.56 -k 2.71,2.88 -k 3.1,3.4 
> ) amp;amp; 
> grep "^G020" oa
> )
G010KR   OLTP    PDOA210105210304210105000000000000000000000000F
G2019998199916        86010027472                       SCBLKRSEXXX860  KRUPMU TEST
G2019998199916        86010027524                       SCBLKRSEXXX860  KRUPMU TEST
G2029998199916        86010027472                       SCBLKRSEXXXKRW-00000000000000000
G2029998199916        86010027524                       SCBLKRSEXXXKRW000000000000000000
G2039998199916        86010027472                       SCBLKRSEXXXKRW201210201210110141
G2049998199916        86010027472                       SCBLKRSEXXXKRW201210201210110141
G2039998199916        86010027472                       SCBLKRSEXXXKRW201210201210141946
G2049998199916        86010027472                       SCBLKRSEXXXKRW201210201210141946
G2039998199916        86010027472                       SCBLKRSEXXXKRW201210201210095900
G2049998199916        86010027472                       SCBLKRSEXXXKRW201210201210095900
G2039998199916        86010027524                       SCBLKRSEXXXKRW201211201211141445
G2049998199916        86010027524                       SCBLKRSEXXXKRW201211201211141445
G2039998199916        86010027524                       SCBLKRSEXXXKRW201210201210163210
G2049998199916        86010027524                       SCBLKRSEXXXKRW201210201210163210
G2039998199916        86010027524                       SCBLKRSEXXXKRW201211201211144629
G2049998199916        86010027524                       SCBLKRSEXXXKRW201211201211144629
G020000011140000000000000000000000.000

[tmp] $ (
> grep "^G010" oa amp;amp; 
> ( 
> grep "^G201" oa|sort -u -k 1.1,1.4 -k 1.23,1.56 amp;amp; 
> grep "^G202" oa|sort -u -k 1.1,1.4 -k 1.23,1.56 amp;amp; 
> grep -E "^(G203|G204|G205|G206)" oa | sort -k 1.23,1.56 -k 2.71,2.88 -k 3.1,3.4 
> ) | sort -k 1.23,1.56 amp;amp; 
> grep "^G020" oa
> )
G010KR   OLTP    PDOA210105210304210105000000000000000000000000F
G2019998199916        86010027472                       SCBLKRSEXXX860  KRUPMU TEST
G2029998199916        86010027472                       SCBLKRSEXXXKRW-00000000000000000
G2039998199916        86010027472                       SCBLKRSEXXXKRW201210201210095900
G2039998199916        86010027472                       SCBLKRSEXXXKRW201210201210110141
G2039998199916        86010027472                       SCBLKRSEXXXKRW201210201210141946
G2049998199916        86010027472                       SCBLKRSEXXXKRW201210201210095900
G2049998199916        86010027472                       SCBLKRSEXXXKRW201210201210110141
G2049998199916        86010027472                       SCBLKRSEXXXKRW201210201210141946
G2019998199916        86010027524                       SCBLKRSEXXX860  KRUPMU TEST
G2029998199916        86010027524                       SCBLKRSEXXXKRW000000000000000000
G2039998199916        86010027524                       SCBLKRSEXXXKRW201210201210163210
G2039998199916        86010027524                       SCBLKRSEXXXKRW201211201211141445
G2039998199916        86010027524                       SCBLKRSEXXXKRW201211201211144629
G2049998199916        86010027524                       SCBLKRSEXXXKRW201210201210163210
G2049998199916        86010027524                       SCBLKRSEXXXKRW201211201211141445
G2049998199916        86010027524                       SCBLKRSEXXXKRW201211201211144629
G020000011140000000000000000000000.000
 

Ответ №1:

Awk был бы идеальным кандидатом для этого (GNU awk для сортировки массива):

 awk 'NR==1 { print;next } $3 == "" { endline=$0;next } { code=substr($1,1,4);map[code][$2][$3]=$0} END {PROCINFO["sorted_in"]="@ind_str_asc";for (i in map) { for (j in map[i]) { for (k in map[i][j]) { print map[i][j][k] } } } print endline }' ootpafile
 

Объяснение:

 awk 'NR==1 { 
             print; # Print the line
             next # Skip to the next line
            } 
   $3 == "" { 
             endline=$0; # Set a variable endline to the current line where the 3rd space delimited field is empty
             next 
            } 
            { 
             code=substr($1,1,4); # Extract the first 4 characters into a variable code
             map[code][$2][$3]=$0 # Store the line in a 3 dimentional array indexed by code and other fields
             } 
         END {
              PROCINFO["sorted_in"]="@ind_str_asc"; # Set the ordering of the array
              for (i in map) { 
                for (j in map[i]) { 
                  for (k in map[i][j]) { 
                     print map[i][j][k] # Loop through the array and print the entries
                  } 
                 } 
               } 
               print endline # Print the end line
              }' ootpa