연속된 단락의 그룹 정렬(빈 줄로 구분)?

연속된 단락의 그룹 정렬(빈 줄로 구분)?

내 생각엔 이제 분류에 꽤 능숙해진 것 같아목록;그러나 지금까지 정렬 방법에 대한 정보를 찾지 못했습니다.연속선.

다음과 같은 텍스트 파일이 있다고 가정해 보겠습니다. (물론 매우 간단합니다.)

Echo
Alpha
Delta
Charlie

Golf
Bravo
Hotel
Foxtrot

이제 영숫자순으로 행을 정렬할 수 있습니까?각 블록은 별도로? 즉, 결과는 다음과 같습니다.

Alpha
Charlie
Delta
Echo

Bravo
Foxtrot
Golf
Hotel

sort매뉴얼 페이지에서 찾은 내용에 따르면 sort내장된 UNIX 명령을 사용하면 이것이 불가능할 수도 있습니다. 아니면 외부/타사 도구를 사용하지 않고도 수행할 수 있습니까?

답변1

awk -v RS= -v cmd=sort '{print | cmd; close(cmd); print ""}' file

레코드 구분 기호를 RS빈 문자열로 설정하면 awk가 한 번에 단락을 단계별로 실행하게 됩니다. 각 단락에 대해 단락( )을 cmd( 로 설정)로 $0파이프하고 sort출력을 인쇄합니다. 로 출력 단락을 구분하기 위해 빈 줄을 인쇄합니다 print "".

Perl 예를 든다면 저는 Stephane의 접근 방식과는 다른 접근 방식을 제안하겠습니다.

perl -e 'undef $/; print join "\n", sort (split /\n/), "\n" 
    foreach(split(/\n\n/, <>))' < file

전체 STDIN을 undef $/사용하고 가져올 수 있도록 하는 필드 구분 기호( )를 설정 해제합니다 . <>그런 다음 (문단) split돌아갑니다 . "단락": 줄 바꿈 주위에 줄을 설정한 다음 다시 모아서 끝에 추가합니다.\n\nforeachsortsplitsortjoin\n

그러나 이는 이전 단락에 없는 경우 마지막 단락에 "후행 단락" 구분 기호를 추가하는 부작용이 있습니다. 약간 덜 아름다운 방법으로 이 문제를 해결할 수 있습니다.

perl -e 'undef $/; print join "\n", sort (split /\n/) , (\$_ == \$list[-1] ? "" : "\n")
    foreach(@list = split(/\n\n/, <>))' < file

이것은 단락을 할당 한 다음 그것이 ( 체크) 의 마지막 요소 @list인지 확인하기 위한 "삼항 연산"을 갖습니다 . ( )이면 인쇄하고, 그렇지 않으면 ( ) 다른 모든 "단락"( 의 요소 )을 인쇄합니다.foreach\$_ == \$list[-1]""? ...: ..."\n"@list

답변2

Drav의 awk솔루션은 훌륭하지만 sort단락당 하나의 명령을 실행하는 것을 의미합니다. 이를 방지하려면 다음을 수행할 수 있습니다.

< file awk -v n=0 '!NF{n++};{print n,$0}' | sort -k1n -k2 | cut -d' ' -f2-

또는 다음을 사용하여 모든 작업을 수행할 수 있습니다 perl.

perl -ne 'if (/\S/){push@l,$_}else{print sort@l if@l;@l=();print}
          END{print sort @l if @l}' < file

위의 구분 기호는 빈 줄 이 아니라 빈 줄 (첫 번째 의 경우 awk공백이나 탭만 포함하는 줄, 첫 번째의 경우 가로 또는 세로 공백 문자)입니다. perl빈 줄을 정말로 원한다면 또는 !NF로 바꾸고 로 바꿀 수 있습니다 .!length$0==""/\S//./

답변3

나는 텍스트 단락에 sort, shuf, tac 또는 기타 명령을 사용할 수 있는 도구를 Haskell로 작성했습니다.

https://gist.github.com/siers/01306a361c22f2de0122
편집: 이 도구는 이 저장소에도 포함되어 있습니다.https://github.com/siers/haskell-import-sort

텍스트를 청크로 분할하고 \0하위 청크를 문자와 연결하고 명령을 통해 파이프한 다음 마지막으로 동일한 작업을 반대로 수행합니다.

2015년 8월 28일: 저는 이 도구를 개인적으로 사용하는 또 다른 방법을 찾았습니다. 한 줄 다음에 N개의 단락을 선택하는 것입니다.

paramap grep -aA2 '^reddit usernames' < ~/my-username-file
reddit usernames

foo
bar
baz

a couple
more of these

답변4

TxRLisp 단계별:

$ cat data
Echo
Alpha
Delta
Charlie

Golf
Bravo
Hotel
Foxtrot

$ txr -p '(get-lines)' < data
("Echo" "Alpha" "Delta" "Charlie" "" "Golf" "Bravo" "Hotel" "Foxtrot")

$ txr -t '(get-lines)' < data
Echo
Alpha
Delta
Charlie

Golf
Bravo
Hotel
Foxtrot

$ txr -p '(partition* (get-lines) (op where [chain length zerop]))' < data
(("Echo" "Alpha" "Delta" "Charlie") ("Golf" "Bravo" "Hotel" "Foxtrot"))

$ txr -p '[mapcar sort (partition* (get-lines) (op where [chain length zerop]))]' < data
(("Alpha" "Charlie" "Delta" "Echo") ("Bravo" "Foxtrot" "Golf" "Hotel"))

$ txr -p '(interpose (list "") [mapcar sort (partition* (get-lines) (op where [chain length zerop]))])' < data
(("Alpha" "Charlie" "Delta" "Echo") ("") ("Bravo" "Foxtrot" "Golf" "Hotel"))

$ txr -t '(interpose (list "") [mapcar sort (partition* (get-lines) (op where [chain length zerop]))])' < data
Alpha
Charlie
Delta
Echo

Bravo
Foxtrot
Golf
Hotel

인용하다:행 가져오기,분할*,작동하다,어디,체인,길이,제로프,지도 자동차,간섭.

관련 정보