-1

このようなファイルがあります

: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-*]との間の後の行[-]はセットです。2列目に従って各セットをソートしたい。並べ替えは、セットのメンバー内でのみ発生する必要があります。

予想される出力は次のとおりです。

: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が苦手です。while loops のような通常のシェルコマンドで試しました。しかし、それを取得できませんでした。並べ替えを実行できる sed または awk のコードを教えてください。

4

3 に答える 3

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
-
于 2013-09-10T15:27:22.470 に答える
1

awkandで行うことはおそらく可能sedですが、簡単な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(': '))
于 2013-09-10T15:29:18.770 に答える
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
-
于 2013-09-10T15:29:28.867 に答える