다음 형식의 텍스트 파일이 있습니다.
####################################
KEY2
VAL21
VAL22
VAL23
VAL24
####################################
KEY1
VAL11
VAL12
VAL13
VAL14
####################################
KEY3
VAL31
VAL32
VAL33
VAL34
이 파일을 한 줄씩 정렬 KEY
하고 결과에 다음 4줄을 유지하고 싶으므로 정렬된 결과는 다음과 같아야 합니다.
####################################
KEY1
VAL11
VAL12
VAL13
VAL14
####################################
KEY2
VAL21
VAL22
VAL23
VAL24
####################################
KEY3
VAL31
VAL32
VAL33
VAL34
이를 수행할 수 있는 방법이 있습니까?
답변1
msort(1)
여러 행의 레코드로 파일을 정렬할 수 있도록 설계되었습니다. 여기에는 선택적인 GUI와 사람이 사용할 수 있는 일반적인 명령줄 버전이 있습니다. (적어도 매뉴얼을 잘 읽고 예제를 찾는 걸 좋아하는 인간들은...)
AFAICT, 레코드에 임의의 패턴을 사용할 수 없으므로 레코드가 고정 크기(문자나 줄이 아닌 바이트 단위)가 아닌 한. 실제로 빈 줄로 구분된 줄 블록을 기록하는 옵션이 msort
있습니다 .-b
-b
각 입력(첫 번째 입력 제외) 앞에 빈 줄을 추가하면 ###...
입력을 쉽게 사용할 수 있는 형식으로 변환 할 수 있습니다.
기본적으로 stderr에 대한 통계를 인쇄하므로 적어도 전체 입력이 단일 레코드라고 생각하므로 정렬되지 않은 시기를 쉽게 알 수 있습니다.
msort
귀하의 데이터에 적용됩니다. 이 명령은 라인 1을 제외한 sed
각 라인 앞에 개행 문자를 추가합니다 . 전체 레코드를 사전순으로 정렬합니다. 레코드의 어느 부분이 키로 사용되는지 선택하는 몇 가지 옵션이 있지만 필요하지 않습니다.#+
-w
또한 추가 줄 바꿈을 제거하는 것을 놓쳤습니다.
$ sed '2,$ s/^#\+/\n&/' unsorted.records | msort -b -w 2>/dev/null
####################################
KEY1
VAL11
VAL12
VAL13
VAL14
####################################
KEY2
VAL21
VAL22
VAL23
VAL24
####################################
KEY3
VAL31
VAL32
VAL33
VAL34
-r '#'
나는 그것을 기록 구분자로 사용하는 데 아무런 행운이 없었습니다 . 전체 파일을 레코드로 간주합니다.
답변2
해결 방법은 먼저 블록 내의 개행 문자를 사용하지 않은 문자(아래 예에서는 "|")로 변경하고 결과를 정렬한 다음 선택한 구분 기호를 다시 원래 개행 문자로 변경하는 것입니다.
sed -e 'N; N; N; N; N; s/\n/|/g' file.txt \
| sort -k2,2 -t\| \
| sed 's/|/\n/g'
답변3
perl -0ne 'print sort /(#+[^#]*)/g' file.txt
perl -0
전체 파일을 먹어라/(....)/g
레코드 일치 및 추출print sort ...
정렬하고 인쇄하세요.
답변4
POSIX awk를 사용할 수 있습니다표준 라이브러리:
#!/usr/local/bin/awklib -f
$0 ~ "#" {x++}
{q[x] = q[x] ? q[x] RS $0 : $0}
END {
arr_sort(q)
for (x in q) print q[x]
}