使用命令行工具对行的子组进行排序

时间:2009-07-22 14:37:09

标签: bash command-line

我一直试图找到一种使用标准命令行工具,bash,awk,sort进行排序的方法,除了使用perl或类似之外无法找到其他方法。

任何提示?

输入数据

header1
3
2
5
1

header2
5
1
3
.....
.....

输出数据

header1
1
2
3
5

header2
1
....

由于

4 个答案:

答案 0 :(得分:3)

假设部分用空行分隔,标题不一定包含字符串“header”。按原始顺序保留部分,以便排序稳定。从标准输入读取,显示在标准输出上。

#!/bin/bash

function read_section() {
    while read LINE && [ "$LINE" ]; do echo "$LINE"; done
}

function sort_section() {
    read HEADER && (echo "$HEADER"; sort; echo)
}

while read_section | sort_section; do :; done

或者作为一个单行:

cat test.txt | while (while read LINE && [ "$LINE" ]; do echo "$LINE"; done) | (read HEADER && (echo "$HEADER"; sort; echo)); do :; done

答案 1 :(得分:1)

试试这个:

mark@ubuntu:~$ cat /tmp/test.txt
header1
3
2
5
1

header2
5
1
3
mark@ubuntu:~$ cat /tmp/test.txt | awk '/header/ {colname=$1; next} {print colname, "," , $0}'  | sort | awk '{if ($1 != header) {header = $1; print header} print $3}'
header1

1
2
3
5
header2
1
3
5

为了摆脱空白行,我想你最后可以添加一个“| grep -v'^ $'”......

答案 2 :(得分:0)

使用AWK将header添加到每个数字行的前缀 sort生成的文件。
删除前缀以将文件恢复为原始格式。

答案 3 :(得分:0)

使用GNU awk,您可以使用其内部排序功能。

awk 'BEGIN{ RS=""}
{
    print $1
    for(i=2;i<=NF;i++){
        a[i]=$i
    }
    b=asort(a,d)
    for(i=1;i<=b;i++){    
        print d[i]
    }
    delete d
    delete a    
} ' file

输出

# more file
header1
3
2
5
1

header2
5
1
3
# ./test.sh
header1
1
2
3
5
header2
1
3
5