여러 줄의 텍스트 파일을 행으로 정렬 텍스트 파일이

이 형식의 텍스트 파일이 있습니다.

####################################
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]
}