2013-07-29 2 views
2

barbaz의 데이터 세트 (foo)가 섹션 '에서 출력됩니다. baz이있는 섹션은 출력 맨 위에 정렬해야합니다.텍스트 섹션 정렬 (유닉스/쉘)

입력 예;

= foo4 = 
bar 
(..) 
barN 
= foo1 = 
bar 
(..) 
barN 
= foo5 = 
bar 
(..) 
barN 
baz 
= foo2 = 
bar 
(..) 
barN 
= foo3 = 
bar 
(..) 
barN 
baz 

위의 예에서, I 즉 목록 섹션 "이름"으로 하위 분류를 섹션 = foo3 == foo5 =가 출력의 상부로 이동, 그리고 것이다.

= foo3 = 
= foo5 = 
= foo1 = 
= foo2 = 
= foo4 = 

그러나 섹션의 내용은 그대로 유지됩니다.

답변

1

Perl 용액. 섹션의 해시를 사용하고, 키는 섹션의 이름이고, 값은 섹션이 시작되는 파일의 위치와 정보가 baz인지 여부를 포함합니다. 파일이 해시로 읽히고 나면 키가 정렬되고 기억 된 파일을 따라 이동하면서 내용이 인쇄됩니다.

#!/usr/bin/perl 
use warnings; 
use strict; 

my $file = shift; 

my $start = qr/^= (.*) =$/; 

open my $FH, '<', $file or die $!; 

my %sections; 
my $current_section; 
while (<$FH>) { 
    if (/$start/) { 
     $current_section = $1; 
     $sections{$current_section}{begin} = tell $FH; 
    } elsif (/baz/) { 
     $sections{$current_section}{baz} = 1; 
    } 
} 

for my $section (map substr($_, 1), 
       sort map { ($sections{$_}{baz} ? '0' : '1') . $_ } 
       keys %sections) { 
    seek $FH, $sections{$section}{begin}, 0; 
    print "= $section =\n"; 
    while (<$FH>) { 
     last if /$start/; 
     print; 
    } 
} 
+0

작품 완전히 같은 광고했다가 빠르고 쉽게 읽을 대답 하시겠습니까과 다시 ++를 읽을 것으로 – Jan

+0

를 제외하고, 나는 또한이 "죽은"/ 빈 섹션들 - 다른'elsif'를 가진 것들을 버릴 수 있습니까? – Jan

+0

@Jan : 빈 섹션은 첫 번째'if' 브랜치를 통과 할 것입니다. 일단'/ baz '를 체크하기 전이라도 비어 있지 않으면 섹션을 비어있게 설정할 수 있습니다 /'. 출력 할 때 빈 섹션을 찾는 것을 건너 뛸 수 있습니다. – choroba

2

Lottastuff 솔루션, 일명, 지방 oneliner는 :

awk '/^=/{print ""} {printf "%s\t", $0}' input.txt | \ 
    awk '{print ($NF != "baz")"\t"$0}' | sort -n | cut -f 2- | \ 
    tr '\t' '\n' | sed -e '/^$/d' 

초기 변환은 너무 까다 롭고 터무니된다. .이 구분 (까지 붙여 줄 수있는 몇 가지 도구가 될해야합니다.

+1

비슷한 접근법을 고려해 보았지만, 결국 너무 지저분 해 보였습니다. 그러나 시간을내어 주셔서 감사합니다 :) – Jan

관련 문제