2016-06-07 2 views
2

sort 유틸리티를 사용하면 편리하게 파일의 행을 정렬 할 수 있습니다. 그러나 bash에서 공백으로 구분 된 단락을 정렬하는 우아한 방법이 있습니까? bash에서 텍스트 파일의 단락 정렬

ccc\naa  
aba\nbbb 
aba\nccc 
aaa 

다음 전화

: 예를 들어

ccc 
aa 

aba 
bbb 

aba 
ccc 

aaa 

aaa 

aba 
bbb 

aba 
ccc 

ccc 
aa 

하나의 해결책이 될 것 이외의 모든 공백 라인에 새로운 라인 기호를 대체 할 것으로 보인다 실행 sort

aaa 
aba\nbbb 
aba\nccc 
ccc\naa  
다음 복원 신규 라인 :

aaa 

aba 
bbb 

aba 
ccc 

ccc 
aa  
+1

'sed'유틸리티가 아니라 'sort'유틸리티를 사용하여 정상적으로 작동하는 이유를 명확히 할 수 있습니까? 나는 그 구별을 정말로 보지 못한다. 어떤 유틸리티가 괜찮습니까? – ruakh

+0

또한 \ n 대신 \ 0을 구분 기호로 사용하여 시스템의 '정렬'지원을합니까? – ruakh

+0

@ruakh 질문을 수정하겠습니다. 나는'sed' 솔루션을 가지고 있다면 실제로 괜찮습니다. – john1234

답변

3

Perl to the rescue;

perl -n00 -e 'push @a, $_; END { print sort @a }' file 

-00 옵션은 빈 줄에 입력을 분할 "단락 모드"를 할 수 있습니다.

견본에서와 같이 마지막 입력 행이 반드시 비어있는 경우가 아니라면 새 행을 별도로 추가해야합니다.

perl -n00 -e 'push @a, $_; 
    END { $a[-1] .= "\n" if $a[-1] !~ /\n\n$/; 
     print sort @a }' file 
+0

나는 처음부터 이것을 아주 좋아했다. 하지만 단락의 줄 바꿈 (필드 사이)이 정렬을 중단하지 않을 것이라고 확신합니까? – hek2mgl

+0

생각하면 유스 케이스에 달려있다. OP가 말한 것을 보자. – hek2mgl

+0

간단한 어휘 정렬입니다. 개행이 끝났습니다. 마지막 단락 뒤에 구분 기호가없는 경우 출력을 약간 조정해야합니다 (OP 입력으로 'aba bbb'바로 옆에 'aaa'가 표시되어 단일 레코드처럼 보입니다). – tripleee

0

은 완벽 하진 될 수 있으나, 이는 입력했다.

#!/bin/bash 

par="" 
while read line 
do 
    if [ "${#line}" -gt 0 ]; then 
read -d '' par <<EOF 
$par 
$line 
EOF 

    fi 
    if [ "${#line}" -eq 0 ]; then 
    sort <<< "$par" 
    par="" 
    echo  
    fi 
done < "${1:-/dev/stdin}" 
0

분리 기호에 인쇄 할 수없는 문자를 사용합니다. \1라고 가정 해 보겠습니다.


그런 다음, 파일을 변환하는 awk를 사용하여 정렬 한 다음 다시 번역 awk를 사용할 수 있습니다

awk '{$1=$1}1' RS='' OFS='\1' file \ 
    | sort -i \ 
    | awk '{$1=$1}1' FS='\1' OFS='\n' ORS='\n\n' 

$1=$1은 어떤 연산 작동하지 않습니다하지만 여전히 재 조립하는 AWK를 알려줍니다 OFS 및/또는 ORS 분리 문자를 사용하여 기록하십시오.

우선 awk 명령 :

  • RS='' 레코드 분리기의 특별한 가치는 모든 로직 구분 것을 사용하여 표현된다. RS이 빈 문자열이면 두 개 이상의 연속 된 새 행이 기본값으로 설정되어 효과적으로 단락별로 분리됩니다. 이 경우 필드는 새 행으로 구분됩니다.
  • OFS='\1'은 출력에서 ​​\1 필드를 구분합니다. 출력 레코드 분리 자의 기본값은 하나의 개행입니다.

이 우리를 제공합니다

ccc<garbage>aa 
aba<garbage>bbb 
aba<garbage>ccc 
aaa 

우리 이제 sort -i 것을.-i이 우리 제공 비 인쇄 문자를 무시 : \1

  • OFS='\n' 의해

    aaa 
    aba<garbage>bbb 
    aba<garbage>ccc 
    ccc<garbage>aa 
    

    제 AWK 명령

    • FS='\1' 스플릿 입력 필드를 개행 출력 필드 구분자를 설정
    • ORS='\n\n' 출력 레코드 분리 문자를 두 개의 개행 문자로 설정합니다. 실제로는 empt y 라인.

    출력 :이 솔루션은 단락 사이에 하나의 줄 바꿈 이상 유지되지 않습니다

    aaa 
    
    aba 
    bbb 
    
    aba 
    ccc 
    
    ccc 
    aa 
    

    참고.

  • 관련 문제