유닉스에서 파일 블록 정렬 [닫기]

유닉스에서 파일 블록 정렬 [닫기]

비슷한 파일이 있습니다.

HR|testing file
BH|100
B2|cat|10
B2|dog|20
BT|4
BH|105
B2|apple|10
B2|banana|20
B2|melon|10
BT|5
BH|102
B2|fan|10
B2|bulb|20
B2|washer|10
B2|dryer|10
BT|6
TR|17

각 청크에 대한 BH 레코드의 두 번째 필드를 기준으로 청크를 정렬해야 합니다. 블록 내의 행은 그대로 유지되어야 합니다. 위 파일의 예상 출력은 다음과 같습니다.

HR|testing file
**BH|100**
B2|cat|10
B2|dog|20
BT|4
**BH|102**
B2|fan|10
B2|bulb|20
B2|washer|10
B2|dryer|10
BT|6
**BH|105**
B2|apple|10
B2|banana|20
B2|melon|10
BT|5
TR|17

답변1

이는 #블록 BH|#헤더 행을 기준으로 오름차순으로 BH|100BH|102블록을 BH|105정렬 하고 작동해야 합니다 ....

awk -v RS='BH|TR' 'NR>1{ seen[NR]=$0; next } { printf $0 }
   END{ TR="TR"seen[NR]; delete seen[NR]; asort(seen);  
        for(x in seen) printf "BH"seen[x]; printf TR }' infile

HR|testing file
BH|100
B2|cat|10
B2|dog|20
BT|4
BH|102
B2|fan|10
B2|bulb|20
B2|washer|10
B2|dryer|10
BT|6
BH|105
B2|apple|10
B2|banana|20
B2|melon|10
BT|5
TR|17

  • 이는 RS='BH|TR'레코드 구분 기호(기본적으로 ewline)로 및 를 정의합니다.BHTR\n

  • 이 블록은 NR>1{ seen[NR]=$0; next }모든 사람에게 실행됩니다.오른쪽로깅하지만 먼저 NR(질소수량오른쪽레코드) 따라서 연관 배열의 키(인덱스)인 각 레코드 번호에 대해 호출됩니다.전체 레코드의 값이 여기에 설정되고 next레코드가 읽혀집니다.

  • 첫 번째 기록이 아닌 경우{ printf $0 }그것. 다음 번에는 이기 때문에 이것은 한 번만 실행됩니다 NR>1.

마지막으로 블록이 END{ ... }실행되고 다음을 수행합니다.

  • 그러면 TR="TR"seen[NR]배열의 마지막 레코드가 복사되어 이름이 지정된 변수에 삽입됩니다.TR그런 다음 배열에서 제거합니다 delete seen[NR].
  • 이렇게 asort(seen)하면 배열이 정렬됩니다.저장된 값을 기반으로 합니다.
  • for(x in seen)우리는 이 배열을 반복 하고printf "BH"seen[x]
  • 마지막으로 복사한 내용을 인쇄합니다.TR.

파일의 첫 번째 줄과 마지막 줄이 마음에 들지 않으면 다음과 같이 할 수도 있습니다.

sed '1d; $d' infile |awk '{printf $0(/^BT/?"\n":"#")}' |sort |tr '#' '\n'

답변2

나는 이 작업을 수행하는 빠르고 쉬운 방법을 찾았습니다. 더 좋은 방법이 있으면 제안해주세요.

헤더 및 트레일러 레코드가 제거되었습니다. 블록의 줄 사이에 줄 구분 기호로 #을 병합하고 넣어서 한 줄로 병합합니다. 특정 필드별로 정렬새 줄로 바꾸기#

gawk '/^HC/ && line {print line; line=""} {line = line ? line"#"$0 : $0} END {print line}' input.txt | sort -t"|" -nk 13 | tr '#' '\n' > finaloutput.txt

관련 정보