awk为什么存储的数组未按相同顺序检索

awk为什么存储的数组未按相同顺序检索,awk,Awk,我有以下数据 SB 1.2.27: SB 1.2.27 SB 1.2.28: SB 1.2.28, SB 1.2.29, SB 1.2.28-29 SB 1.2.29: SB 1.2.28, SB 1.2.29, SB 1.2.28-29 SB 1.2.30: SB 1.2.30 SB 1.3.1: SB 1.3.1 SB 1.21.1: SB 1.21.1 我使用下面的脚本来提取第二列中唯一的部分 我得到的结果是: SB 1.2.28-29: SB 1.2.28, SB 1.2.29, SB

我有以下数据

SB 1.2.27: SB 1.2.27
SB 1.2.28: SB 1.2.28, SB 1.2.29, SB 1.2.28-29
SB 1.2.29: SB 1.2.28, SB 1.2.29, SB 1.2.28-29
SB 1.2.30: SB 1.2.30
SB 1.3.1: SB 1.3.1
SB 1.21.1: SB 1.21.1
我使用下面的脚本来提取第二列中唯一的部分

我得到的结果是:

SB 1.2.28-29: SB 1.2.28, SB 1.2.29, SB 1.2.28-29
SB 1.2.30: SB 1.2.30
SB 1.2.27: SB 1.2.27
SB 1.3.1: SB 1.3.1
SB 1.21.1: SB 1.21.1
我期待着:

SB 1.2.27: SB 1.2.27
SB 1.2.28-29: SB 1.2.28, SB 1.2.29, SB 1.2.28-29
SB 1.2.30: SB 1.2.30
SB 1.3.1: SB 1.3.1
SB 1.21.1: SB 1.21.1
而且也不是

SB 1.2.27: SB 1.2.27
SB 1.2.28-29: SB 1.2.28, SB 1.2.29, SB 1.2.28-29
SB 1.2.30: SB 1.2.30
SB 1.21.1: SB 1.21.1  (* this should be next)
SB 1.3.1: SB 1.3.1

我的标准方法是使用第二个数值索引数组,如

awk 'BEGIN{FS=": "; num_elms = 0;}{
    if not ($2 in sloka) {
        num_elms++
        lookup[num_elms] = $2
    }
    # I want only the dash part not the whole $2. eg: SB 1.2.28-29
    if(match($0,/(SB [0-9]+\.[0-9]+\.[0-9]+-[0-9]+)$/,hare)){
        sloka[$2] = hare[1]
    }else{
        sloka[$2]= $1
    }
}END{
    for (i = 1; i <= num_elms; i++){
        print sloka[lookup[i]]": "lookup[i]
    }
}' DATA.TXT

注意:我没有对此进行测试,但它显示了模式。

我的标准方法是使用第二个数字索引数组,如

awk 'BEGIN{FS=": "; num_elms = 0;}{
    if not ($2 in sloka) {
        num_elms++
        lookup[num_elms] = $2
    }
    # I want only the dash part not the whole $2. eg: SB 1.2.28-29
    if(match($0,/(SB [0-9]+\.[0-9]+\.[0-9]+-[0-9]+)$/,hare)){
        sloka[$2] = hare[1]
    }else{
        sloka[$2]= $1
    }
}END{
    for (i = 1; i <= num_elms; i++){
        print sloka[lookup[i]]": "lookup[i]
    }
}' DATA.TXT

注意:我没有测试这个,但它显示了模式。

真的不清楚你想做什么-是这样吗

$ awk -F'[:,] ' '!seen[$NF]++{sub(/[^:]+/,$NF); print}' file
SB 1.2.27: SB 1.2.27
SB 1.2.28-29: SB 1.2.28, SB 1.2.29, SB 1.2.28-29
SB 1.2.30: SB 1.2.30
SB 1.3.1: SB 1.3.1
SB 1.21.1: SB 1.21.1

真的不清楚你想做什么-是这样吗

$ awk -F'[:,] ' '!seen[$NF]++{sub(/[^:]+/,$NF); print}' file
SB 1.2.27: SB 1.2.27
SB 1.2.28-29: SB 1.2.28, SB 1.2.29, SB 1.2.28-29
SB 1.2.30: SB 1.2.30
SB 1.3.1: SB 1.3.1
SB 1.21.1: SB 1.21.1

在awk中,所有数组实际上都是散列。如果你用数字索引它们,就有可能保持顺序。如果使用字符串进行索引,则没有orderok。我不知道,我要试试看index@SanthoshYedidi:您正在使用GNU awk吗?awk之后-版本号为awk 4.2.1,API:2.0 GNU MPFR 4.0.2,GNU MP 6.1.2在awk中所有数组实际上都是散列。如果你用数字索引它们,就有可能保持顺序。如果使用字符串进行索引,则没有orderok。我不知道,我要试试看index@SanthoshYedidi:您正在使用GNU awk吗?awk后版本-版本号NU awk 4.2.1,API:2.0 GNU MPFR 4.0.2,GNU MP 6.1.2它将用-重复这些值。但是现在我可以得到唯一的值了,我对脚本做了一些修改。这可能满足您的需要Nowk内置字段、字符串位置和数组索引都从1开始,而不是从0开始,因此您应该对用户定义的数组执行相同的操作,以避免任何混淆-您不需要num_elms=0;这是默认值,然后执行查找[++num_elms]=$2,而不是查找[num_elms]=$2;num_elms++并为i=1创建循环;我@Ed Morton我已经添加了你的一些建议。我认为如果变量被初始化,这不应该被视为一个缺陷。此外,我个人不喜欢在为数组单元格赋值时增加索引。我不保存任何作业,作业后的增量对我来说更容易阅读。我尽量保留OP的原始代码。这使OP更容易理解这些变化。@EdMorton感谢您指出这一点。修好了。C程序员应该坚持从零开始计数-它将使用-,重复这些值。但是现在我可以得到唯一的值了,我对脚本做了一些修改。这可能满足您的需要Nowk内置字段、字符串位置和数组索引都从1开始,而不是从0开始,因此您应该对用户定义的数组执行相同的操作,以避免任何混淆-您不需要num_elms=0;这是默认值,然后执行查找[++num_elms]=$2,而不是查找[num_elms]=$2;num_elms++并为i=1创建循环;我@Ed Morton我已经添加了你的一些建议。我认为如果变量被初始化,这不应该被视为一个缺陷。此外,我个人不喜欢在为数组单元格赋值时增加索引。我不保存任何作业,作业后的增量对我来说更容易阅读。我尽量保留OP的原始代码。这使OP更容易理解这些变化。@EdMorton感谢您指出这一点。修好了。C程序员应该坚持从零开始计数-对现在正确了!看到[$NF]++根据最后一列值分隔,然后替换。是。现在正确了!看到[$NF]++根据最后一列值分隔,然后替换。