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
내보내기 도구를 사용하세요.sort
Randal 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}에게 감사드립니다)