숫자와 텍스트 aix를 사용하여 3개의 다른 열을 기준으로 정렬

숫자와 텍스트 aix를 사용하여 3개의 다른 열을 기준으로 정렬

AIX 시스템에서 3개의 다른 열을 올바른 순서로 정렬하려고 합니다.

다음은 여는 괄호 사이의 최대 실행 시간(예: 0시간 0분 1.030초)을 보여주는 더 큰 파일에서 발췌한 것입니다. 파일의 출력이 병렬로 실행되기 때문에 첫 번째 열은 순서대로 정렬되지 않습니다. 다음은 2500개 행에서 추출한 가장 오래 실행되는 프로세스 10개입니다. 이제 가장 오랫동안 실행된 상위 10개 프로세스를 가장 짧은 시간부터 가장 긴 시간 순으로 정렬하고 싶습니다.

2023-01-04 12:32:08:       Table seqhi completed     (0 hrs 0 mins 1.020 Secs)
2023-01-04 12:32:09:       Table iinvd completed     (0 hrs 0 mins 1.028 Secs)
2023-01-04 12:32:10:       Table iaudl completed     (0 hrs 0 mins 1.030 Secs)
2023-01-04 12:32:11:       Table ccdd_save completed    (1 hrs 0 mins 1.021 Secs)
2023-01-04 12:32:13:       Table upi_brordrep_tmp_aj completed       (0 hrs 0 mins 1.028 Secs)
2023-01-04 12:32:07:       Table srdel completed     (0 hrs 2 mins 1.592 Secs)
2023-01-04 12:32:09:       Table iibt completed      (0 hrs 0 mins 1.020 Secs)
2023-01-04 12:32:10:       Table atprdd completed    (0 hrs 0 mins 1.018 Secs)
2023-01-04 12:33:43:       Table atseld completed    (0 hrs 1 mins 33.868 Secs)
2023-01-04 12:32:10:       Table abc_irctd completed         (0 hrs 0 mins 1.029 Secs)

위의 내용을 다음과 같이 시간, 분, 초별로 정렬하고 싶습니다.

2023-01-04 12:32:10:       Table atprdd completed    (0 hrs 0 mins 1.018 Secs)
2023-01-04 12:32:08:       Table seqhi completed     (0 hrs 0 mins 1.020 Secs)
2023-01-04 12:32:09:       Table iibt completed      (0 hrs 0 mins 1.020 Secs)
2023-01-04 12:32:09:       Table iinvd completed     (0 hrs 0 mins 1.028 Secs)
2023-01-04 12:32:13:       Table upi_brordrep_tmp_aj completed       (0 hrs 0 mins 1.028 Secs)
2023-01-04 12:32:10:       Table abc_irctd completed         (0 hrs 0 mins 1.029 Secs)
2023-01-04 12:32:10:       Table iaudl completed     (0 hrs 0 mins 1.030 Secs)
2023-01-04 12:33:43:       Table atseld completed    (0 hrs 1 mins 33.868 Secs)
2023-01-04 12:32:07:       Table srdel completed     (0 hrs 2 mins 1.592 Secs)
2023-01-04 12:32:11:       Table ccdd_save completed    (1 hrs 0 mins 1.021 Secs)

몇 가지 정렬 명령을 시도했지만 원하는 것을 얻는 데 문제가 있습니다. 이것이 어떻게 달성될 수 있습니까?

답변1

타임스탬프와 기간 사이의 텍스트에 항상 공백으로 구분된 3개의 단어가 있다고 가정하면(예제 참조) 다음을 수행할 수 있습니다.

<your-file LC_ALL=C sort -nb -k6.2,6 -k8,8 -k10,10

기본 구분 기호는 sort공백이 아닌 공백과 공백 사이의 전환이므로 없는 정렬 키에는 -b선행 공백이 포함됩니다. 를 사용하여 이를 제거하려면 -b여섯 번째 필드의 두 번째 문자부터 시작하도록 지정된 첫 번째 키가 바로 거기에 있는지 확인합니다 (.

모든 키는 n숫자로 해석됩니다. 를 사용하면 LC_ALL=C십진수 기수 문자가 .사용자의 로케일과 독립적이어야 함을 보장합니다.

초와 분 부분이 60을 초과하지 않는다고 가정합니다. 예를 들어 후자가 더 길더라도 (0 hrs 1 mins 10.1 Secs)나중에 순위가 매겨집니다.(0 hrs 0 mins 120.592 Secs)

파이프라인을 통해 tail상위 10위를 얻으세요 .


정렬 키가 고정 오프셋이 있는 필드 또는 필드의 일부일 수 없는 경우 일반적인 접근 방식은 다른 도구를 사용하여 키를 추출하고 행 시작 부분에 복사한 다음 정렬하고 삭제하는 것입니다.안에장식-정렬-장식 취소패션:

d='\([[:digit:]]\{1,\}\)'
<your-file sed -n "s/^.*($d hrs $d mins $d\.$d Secs)\$/\1:\2:\3.\4:&/p" |
  LC_ALL=C sort -nt: -k1,1 -k2,2 -k3,3 |
  cut -d: -f4-

또는 내장된 연산자 와 함께 perl최고의 e추출 및 r내보내기 도구를 사용하세요.sortRandal L. Schwartz는 "장식-정렬-장식 해제"라는 관용구의 이름을 따서 명명되었습니다.일반적으로 다음을 사용합니다.

<your-file perl -ne '
   push @records, [$_, $3 + 60 * ($2 + 60 * $1)]
     if /\((\d+) hrs (\d+) mins (\d+\.\d+) Secs\)$/;
   END {print $_->[0] for sort {$a->[1] <=> $b->[1]} @records}'

또는 사용@terdon의 접근 방식동일한 기간의 행을 중복 제거하면 먼저 정렬 프로세스 중에 일부 비교가 절약되지만 해시 테이블을 운영하는 비용이 발생하여 결국 효율성 측면에서 비생산적일 수 있으며 궁극적으로 정렬 안정성이 손실될 수 있습니다.

답변2

펄 방법:

$ perl -lne '/(\d+)\s*hrs\s*(\d+)\s*mins\s*([0-9.]+)\s*Secs/; 
             push @{$k{($1*60*60)+($2*60)+($3)}},$_; 
             }{ 
             for $t (sort {$a <=> $b} keys(%k)){
                print join "\n",@{$k{$t}}
            }; ' file
2023-01-04 12:32:10:       Table atprdd completed    (0 hrs 0 mins 1.018 Secs)
2023-01-04 12:32:08:       Table seqhi completed     (0 hrs 0 mins 1.020 Secs)
2023-01-04 12:32:09:       Table iibt completed      (0 hrs 0 mins 1.020 Secs)
2023-01-04 12:32:09:       Table iinvd completed     (0 hrs 0 mins 1.028 Secs)
2023-01-04 12:32:13:       Table upi_brordrep_tmp_aj completed       (0 hrs 0 mins 1.028 Secs)
2023-01-04 12:32:10:       Table abc_irctd completed         (0 hrs 0 mins 1.029 Secs)
2023-01-04 12:32:10:       Table iaudl completed     (0 hrs 0 mins 1.030 Secs)
2023-01-04 12:33:43:       Table atseld completed    (0 hrs 1 mins 33.868 Secs)
2023-01-04 12:32:07:       Table srdel completed     (0 hrs 2 mins 1.592 Secs)
2023-01-04 12:32:11:       Table ccdd_save completed    (1 hrs 0 mins 1.021 Secs)

제한은 없습니다스티븐의 대답(0 hrs 1 mins 10.1 Secs), 이전에는 올바르게 정렬됩니다 (0 hrs 0 mins 120.592 Secs). 반면에 이것은 가능성이 낮은 문제처럼 보이며 Stéphane의 방법은 간단하고 빠르기 때문에 60초 이상 걸리는 경우를 알지 않는 한 저는 그 방법을 대신 사용하겠습니다.

답변3

나에게 익숙한 "sort" 명령은 숫자순이 아닌 알파벳순으로 정렬하므로(10,11,12는 6,7,8 이전에 정렬) -k 문자열 뒤에 "g"를 추가해야 할 수도 있습니다(예: "-k8 "-k8,8" 대신 ,8g")를 사용하면 숫자로 정렬할 수 있습니다.

답변4

경고: 현재 답변의 첫 번째 줄은 (GNU)sort 명령으로, 일반 AIX 시스템에서는 작동하지 않습니다. (때로는 gsort라는 이름으로 gnu-sort가 설치되기도 합니다)

sort -k6Vb example

어디:

  • -k6필드 6부터 끝까지 정렬하는 데 사용됩니다.
  • Vb버전 정렬(사람의 직관에 따른 순서)에서 선행 공백을 무시하는지 여부

(\{Jeff와 Stephen}에게 감사드립니다)

관련 정보