在一组行之间进行排序

时间:2013-09-10 15:07:31

标签: linux shell sed awk

我有一个像这样的文件

:A-73
113: 44
77: 63
75: 56
-
:A-70
63: 58
59: 64
57: 53
51: 57
12: 72
-
:A-66
65: 61
63: 58
59: 64
57: 53
-
:A-119
77: 63
75: 56
65: 61
-

[:A-*][-]之间的行是一组。我想根据第二列对每组进行排序。排序应仅在集合的成员中进行。

预期输出为:

:A-73
113: 44
75: 56
77: 63
-
:A-70
57: 53
51: 57
63: 58
59: 64
12: 72
-
:A-66
57: 53
63: 58
65: 61
59: 64
-
:A-119
75: 56
65: 61
77: 63

我不擅长awk。我尝试使用通常的shell命令,比如while循环;但无法得到它。能否请您提供可以进行排序的sed或awk代码。

3 个答案:

答案 0 :(得分:3)

#!/bin/bash

# Sort a single section. This is called in a loop.
sortSection() {
    # Read and echo the `:A' header. If that fails, return an error code.
    read header || return
    echo "$header"

    # Read all the lines up until a `-' or EOF and pipe them to `sort'.
    while read line && [[ $line != '-' ]]; do
        echo "$line"
    done | sort -k 2 -n

    # Echo the final `-' manually since it was consumed by the loop.    
    echo '-'
}

# Run `sortSection' repeatedly until it fails, indicating EOF.
while sortSection; do :; done

输出:

$ ./sortSections < sets
:A-73
113: 44
75: 56
77: 63
-
:A-70
57: 53
51: 57
63: 58
59: 64
12: 72
-
:A-66
57: 53
63: 58
65: 61
59: 64
-
:A-119
75: 56
65: 61
77: 63
-

答案 1 :(得分:1)

可能可以在awksed中执行,但这是一个简单的Python解决方案:

#!/usr/bin/env python2

import fileinput

head = None
lines = []

for line in fileinput.input():
    line = line.rstrip()
    if head is None:
        head = line
        lines = []
    elif line == '-':
        lines.sort(key=lambda x:int(x[1]))
        print head
        for l in lines:
            print ': '.join(l)
        print line
        head = None
    else:
        lines.append(line.split(': '))

答案 2 :(得分:1)

如果每个块中的重复项都不是问题,那么:

/^:A-/ {                                 # if line start with :A-
    print                                # print the current line
    next                                 # go grab the next line
} 
/^-$/ {                                  # if line is a single -

    n = asort(value)                     # sort the lines in the array

    for (i=1;i<=n;i++) {                 # loop over all the lines
        print key[value[i]],value[i]     # print the lines in sorted order
    }

    print                                # print the current line

    delete key                           # delete the entries in the arrays 
    delete value
    next                                 # go grab the next line
}

{                                        # else line needs sorting
    value[$1] = $2                       # store the second field
    key[$2] = $1                         # store the first field
}

将其保存到sort.awk等文件中并运行如下:

$ awk -f sort.awk file
:A-73
113: 44
75: 56
77: 63
-
:A-70
57: 53
51: 57
63: 58
59: 64
12: 72
-
:A-66
57: 53
63: 58
65: 61
59: 64
-
:A-119
75: 56
65: 61
77: 63
-