如何在Linux shell中将包含两个集合的文件排序为两个按字母顺序排列的集合?

时间:2017-01-14 03:51:24

标签: bash shell sorting text gnu-sort

我在一个文本文件中有两组相似的数据,我希望按字母顺序对这些组的内容进行独立排序。以下文本块是文本文件的一部分,格式为name : value

set1 :
scripts : 1168
virt : 541
firmware : 15
init : 315
security : 1529

set2 :    
scripts : 873
init : 84
virt : 402
security : 1720
firmware : 6

我希望输出按如下方式排序:

set1 :
firmware : 15
init : 315
scripts : 1168
security : 1529
virt : 541

set2 :    
firmware : 6
init : 84
scripts : 873
security : 1720
virt : 402

经过对此问题的快速研究后,我找到了以下解决方案:

  1. 将文件分成两半,然后尝试独立排序 这不是首选,因为我需要收集这些结果 来自1000多个文件。
  2. 使用Linux GNU sort命令,该命令有点问题。它按字母顺序对两组进行排序,然后根据namesvalues进行排序。这意味着,使用GNU sort,我将丢失某些行的集合成员资格。
  3. GNU sort的结果是已排序但在此问题的上下文中不正确。

    firmware : 15
    firmware : 6
    init : 315
    init : 84
    scripts : 1168
    scripts : 873
    security : 1529
    security : 1720
    set1 :
    set2 :
    virt : 402
    virt : 541
    

1 个答案:

答案 0 :(得分:3)

BEGIN {
RS="set"
FS="\n"
}

{
# Skip empty sets
if ($0 == "") next

setname = "set"$1
print setname

i = 0
# Start at field 2 to skip first field which is part of "set" name
for (x=2; x<NF; x++) {
    # Ignore blank lines in set
    if ($x != "") {
        data[i] = $x
        i = i + 1
    }
}
n = asort(data)  # NOTE: asort indexes from 1
for (i=1; i<=n; i++) {
    print data[i]
}
delete data
}

根据OP输入运行以上内容:

awk -f sort.awk input.txt

set1 :
firmware : 15
init : 315
scripts : 1168
security : 1529
virt : 541
set2 :
firmware : 6
init : 84
scripts : 873
security : 1720
virt : 402