이 형식의 텍스트 파일이 있습니다.
####################################
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
이 방법이 있습니까?
답변
msort(1)
여러 줄 레코드로 파일을 정렬 할 수 있도록 설계되었습니다. 선택적인 gui와 일반 및 사용 가능한 사람 명령 행 버전이 있습니다. (적어도 매뉴얼을주의 깊게 읽고 예제를 찾는 사람은 …)
AFAICT에서는 레코드에 임의의 패턴을 사용할 수 없으므로 레코드의 크기가 고정되어 있지 않은 경우 (문자 또는 행이 아닌 바이트 단위). 빈 행으로 구분 된 행 블록 인 레코드에 msort
대한 -b
옵션 이 있습니다 .
-b
빈 줄을 매번 ###...
(첫 번째 줄 제외) 앞에 두어 입력을 매우 쉽게 작동하는 형식으로 변환 할 수 있습니다 .
기본적으로 stderr에 통계를 인쇄하므로 적어도 전체 입력이 단일 레코드라고 생각하여 정렬되지 않은시기를 쉽게 알 수 있습니다.
msort
데이터에서 작동합니다. 이 sed
명령 #+
은 줄 1을 제외한 모든 줄 앞에 줄 바꿈을 추가합니다 -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 '#'
레코드 구분자로 사용하는 데 운이 없었습니다 . 전체 파일이 하나의 레코드라고 생각했습니다.
답변
해결책은 먼저 블록 내부의 줄 바꿈을 사용하지 않는 선택한 문자 (아래 예에서 ‘|’)로 변경하고 결과를 정렬하고 선택한 구분 기호를 원래 줄 바꿈으로 다시 변경하는 것입니다.
sed -e 'N; N; N; N; N; s/\n/|/g' file.txt \
| sort -k2,2 -t\| \
| sed 's/|/\n/g'
답변
perl -0ne 'print sort /(#+[^#]*)/g' file.txt
perl -0
전체 파일을 빼다/(....)/g
레코드를 일치시키고 추출print sort ...
정렬하고 인쇄
답변
KEY
섹션 에서 여러 줄로 작업해야하는 다른 방법은 다음과 같습니다 .
# extract delimiter
delim=$(head -n1 <infile)
sed '/#/d;/KEY/h;G;s/\n/\x02/' infile | nl -ba -nrz -s $'\002' | sort -t $'\002' -k3 -k1,1 |
cut -d $'\002' -f2 | sed '/KEY/{x;s/.*/'"${delim}"'/;G}'
이것은 구분자를 변수에 저장 한 다음 입력에서 제거하여 작동합니다. 그런 다음 KEY*
낮은 ASCII 문자를 사용하여 해당 섹션의 각 줄에 구분 기호로 추가 한 다음 동일한 구분 기호를 사용하여 n
모든 ines 를 umbers합니다 l
. 그런 다음 sort
세 번째와 첫 번째 필드 만 사용하고 cut
중간 열을 팅한 다음 final을 통해 구분 기호를 복원하는 것 sed
입니다. 위와 함께 KEY12
정렬하기 전에 필요에 KEY2
따라 sort
명령을 조정하십시오 .
답변
POSIX Awk stdlib 라이브러리를 사용할 수 있습니다 .
#!/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]
}