내 생각엔 이제 분류에 꽤 능숙해진 것 같아목록;그러나 지금까지 정렬 방법에 대한 정보를 찾지 못했습니다.연속선.
다음과 같은 텍스트 파일이 있다고 가정해 보겠습니다. (물론 매우 간단합니다.)
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\n
foreach
sort
split
sort
join
\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