파일을 정렬하고 싶습니다.
입력하다:
I1, -2
I2, -6
I2, -9
I1, -8
I1, -1
I3, -7
I2, -4
I3, -4
산출:
I2, -9
I2, -6
I2, -4
I1, -8
I1, -2
I1, -1
I3, -7
I3, -4
아래 출력을 어떻게 얻을 수 있습니까?
답변1
더러운 해결책은 다음과 같습니다.
<infile sort -t, -rk2,2 \
|awk -F, '{ seen[$1]= (seen[$1]==""? "\0":seen[$1] ORS) $0 }
END{ for (x in seen) print seen[x] }' \
|sort -z -t, -rk2,2 \
|tr -d '\0'
분해:
<infile sort -t, -rk2,2
그러면r
입력 파일이 역순으로 정렬 됩니다.infile
두 번째 필드(쉼표는 구분 기호)는k
ey 필드 역할을 합니다.이것앗코드는 단순히 동일한 첫 번째 열로 레코드를 재정렬하여 각 그룹을 구분합니다.유효하지 않은특징
\0
.sort -z -t, -rk2,2
-z
이 역방향 정렬은 두 번째 필드와 쉼표로 구분된 필드(널 문자로 구분, Tell-sort 명령 사용)에서 이러한 블록을 정렬합니다. 이 단계를 실행하기 전에 다음 출력을 검토하고cat -A
표시되는 내용을 추가하세요.^@I1, -8$ I1, -2$ I1, -1$ ^@I2, -9$ I2, -6$ I2, -4$ ^@I3, -7$ I3, -4$
^@
문자는 널 문자를 나타냅니다.sort -z
위 입력은 다음과 같습니다(사람의 가독성과 이해를 돕기 위해 이렇게 했습니다).^@I1, -8$ I1, -2$ I1, -1$ ^@I2, -9$ I2, -6$ I2, -4$ ^@I3, -7$ I3, -4$
당신은 아이디어를 얻었습니다. 위의 정렬 명령은 두 번째 필드를 다음과 같이 봅니다.
-8$ I1 -9$ I2 -7$ I3
...이를 역순으로 정렬하면 결과는 다음과 같이 변경됩니다.
^@I2, -9$ I2, -6$ I2, -4$ ^@I1, -8$ I1, -2$ I1, -1$ ^@I3, -7$ I3, -4$
...구조체를 반환하면 실제로 다음과 같은 결과가 나타납니다.
^@I2, -9$ I2, -6$ I2, -4$ ^@I1, -8$ I1, -2$ I1, -1$ ^@I3, -7$ I3, -4$
tr -d '\0'
결과에서 추가된 널 문자가 제거되고 최종 출력은 다음과 같습니다.I2, -9 I2, -6 I2, -4 I1, -8 I1, -2 I1, -1 I3, -7 I3, -4
답변2
GNU 사용 awk
:
gawk '
grp[$1] == "" || $2 < grp[$1] { grp[$1] = $2 }
{ val[$1][$2] }
END {
PROCINFO["sorted_in"] = "@val_num_asc"
for (i in grp) {
PROCINFO["sorted_in"] = "@ind_num_asc"
for (j in val[i]) print i,j
}
}' ./file
아이디어는 다음과 같습니다.
grp
배열에 있는 열 1의 각 고유 값에 대해 열 2의 최소값을 저장합니다.- 각 행을 2D 배열에 저장하면 열 1의 각 고유 값에 대해 열 2의 값을 쉽게 검색할 수 있습니다( 데이터의 원래 간격을 유지하고 사용할
val
수도 있음 ).val[$1][$2] = $0
print val[i][j]
- 해당 요소의 값을 기준으로 배열을 반복
PROCINFO["sorted_in"]
하고 해당 인덱스 값을 기준으로 (항상 오름차순으로 정렬) (단일) 배열을 반복하는 데 사용됩니다. 열 2와 동일한 최소값을 공유하는 열 1 값의 정렬 순서를 변경하려는 경우(예: 샘플 데이터에 추가하고 출력하기 전에 정렬하려는 경우) 직접 정의해야 할 수도 있습니다. 정렬 기능) .grp
val[i]
I4, -9
I4
I2
다음을 기반으로 하는 휴대용 대안슈워츠 변환, 아마도:
sort -k2,2n ./file |
awk '
grp[$1] == "" { grp[$1] = $2 }
{ print grp[$1] "," $0 }' |
sort -t, -k 1,1n -k 2,2 -k 3,3n |
cut -d, -f2-
여기서 "그룹당"(즉, 열 1의 값에 상대적) 열 2의 최소값은 각 행의 앞에 추가되어 각 그룹( -9
, -8
, -7
)의 최소값을 기준으로 후속 정렬이 가능합니다. 열 1(그룹화된 행을 유지하기 위해), 열 2의 값은
awk
정렬된 데이터를 제공하여 스크립트를 더 간단하게 만듭니다. 각 행에 대해 행이 충족될 때 각 그룹의 최소값이 이미 알려져 있으므로 그럴 필요가 없습니다. 일부 구조 라인에 저장하고 END
블록으로 인쇄합니다(또는 파일을 두 번 처리).