Sorting text sections (unix / shell)

I have some data sets ( foo ) with bar and baz as output in sections'. Sections with baz should be sorted to be at the top of the output.

Example input;

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

In above example, I would like section = foo3 = and = foo5 = to be moved to the top of the output, and have the list sub-sorted by section "name", ie.

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

but with the contents of the section intact.

Perl solution. It uses a hash of sections, the key is the name of a section, the value contains the position in the file where the section starts and the information whether baz was present. Once the file is read into the hash, the keys are sorted and the contents is printed, moving around the file as remembered.

#!/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;
    }
}
我来评几句
登录后评论

已发表评论数()

相关站点

+订阅
热门文章