String 在大型txt上使用awk提取字段的特定字符

String 在大型txt上使用awk提取字段的特定字符,string,if-statement,text,awk,substring,String,If Statement,Text,Awk,Substring,我有一个大的txt文件(“,”作为分隔符),其中包含一些数据和字符串: 2014:04:29:00:00:58:GMT: subject=BMRA.BM.T_GRIFW-1.FPN, message={SD=2014:04:29:00:00:00:GMT,SP=5,NP=3,TS=2014:04:29:01:00:00:GMT,VP=4.0,TS=2014:04:29:01:29:00:GMT,VP=4.0,TS=2014:04:29:01:30:00:GMT,VP=3.0} 2014:04:2

我有一个大的txt文件(“,”作为分隔符),其中包含一些数据和字符串:

2014:04:29:00:00:58:GMT: subject=BMRA.BM.T_GRIFW-1.FPN, message={SD=2014:04:29:00:00:00:GMT,SP=5,NP=3,TS=2014:04:29:01:00:00:GMT,VP=4.0,TS=2014:04:29:01:29:00:GMT,VP=4.0,TS=2014:04:29:01:30:00:GMT,VP=3.0}
2014:04:29:00:00:59:GMT: subject=BMRA.BM.T_GRIFW-2.FPN, message={SD=2014:04:29:00:00:00:GMT,SP=5,NP=2,TS=2014:04:29:01:00:00:GMT,VP=3.0,TS=2014:04:29:01:30:00:GMT,VP=3.0}
我想找到包含“T_GRIFW”的行,然后从“subject”开始打印$1字段,从$2开始只打印时间和浮动。此外,我想合并一个if语句,以便如果字段$4=='NP=3',则在前面的字段之后只打印字段$5、$6、$9、$10,如果$4=='NP=2',则打印以下所有字段(仅限时间和浮动)

例如,两条采样线的结果将是:

subject=BMRA.BM.T_GRIFW-1.FPN,2014:04:29:00:00:00,5,3,2014:04:29:01:00:00,4.0,2014:04:29:01:30:00,3.0
subject=BMRA.BM.T_GRIFW-2.FPN,2014:04:29:00:00:00,5,2,2014:04:29:01:00:00,3.0,2014:04:29:01:30:00,3.0
我知道这很复杂,我已经尽力在我的描述中透彻。到目前为止,我掌握的基本准则是:

awk 'BEGIN {FS=","}{OFS=","} /T_GRIFW-1.FPN/ {print $1}' tib_messages.2014-04-29

万分感谢

如果我了解您的要求,以下几点可以:

BEGIN {
    FS=","
    OFS=","
}

/T_GRIFW/ {
    split($1, subject, " ")
    result = subject[2] OFS
    delete arr
    counter = 1
    for (i = 2; i <= NF; i++) {
        add = 0
        if ($4 == "NP=3") {
            if (i == 5 || i == 6 || i == 9 || i == 10) {
                add = 1
            }
        }
        else if ($4 == "NP=2") {
            add = 1
        }

        if (add) {
            counter = counter + 1
            split($i, field, "=")
            if (match(field[2], "[0-9]*\.[0-9]+|GMT")) {
                arr[counter] = field[2]
            }
        }
    }

    for (i in arr) {
        gsub(/{|}/,"", arr[i]) # remove curly braces
        result = result arr[i] OFS
    }
    print substr(result, 0, length(result)-1)
}
开始{
FS=“,”
OFS=“,”
}
/T_GRIFW/{
拆分($1,主题“”)
结果=受试者[2]OFS
删除arr
计数器=1

对于(i=2;i,这里有一个awk可执行文件,用于创建所需的输出:

#!/usr/bin/awk -f

# use a more complicated FS => field numbers counted differently
BEGIN { FS="=|,"; OFS="," }

$2 ~ /T_GRIFW/ && $8=="NP" {
    str="subject=" $2 OFS

    # strip ":GMT" from dates and "}" from everywhere
    gsub( /:GMT|[\}]/, "")

    # append common fields to str with OFS
    for(i=5;i<=13;i+=2) str=str $i OFS

    # print the remaining fields and line separator
    if($9==3) { print str $19, $21 }
    else if($9==2) { print str $15, $17 }
}
我已经在脚本中添加了注释,但以下是一些可以更好地表述的内容:

  • 使用更复杂的
    FS
    意味着您不需要重新分析
    =
    来处理字段数据
  • 我“作弊”,只是硬编码
    主题
    (现在落在
    $1
    末尾)用于
    str
  • :GMT
    }
    似乎是唯一需要强制删除的数据
  • 使用此
    FS
    日期和数字彼此分开,但仍然可以循环
  • 在最后的
    print
    调用中,
    str
    已经以
    OFS
    结尾,因此可以跳过它和下一个字段之间的逗号

到目前为止你没有多少。再努力一点!你的输出没有意义,因为它不符合你的条件。你说如果
NP=3
,那么只应该打印$5、$6、$9、$10字段。嗨,Ooga,很抱歉模棱两可,我的意思是,此后只应该打印$5、$6、$9、$10。非常感谢你。安!!我很高兴这里还有一些人对我们中一些努力学习诀窍的人要有极大的耐心!非常感谢n0741337和S.Ahn!
subject=BMRA.BM.T_GRIFW-1.FPN,2014:04:29:00:00:00,5,3,2014:04:29:01:00:00,4.0,2014:04:29:01:30:00,3.0
subject=BMRA.BM.T_GRIFW-2.FPN,2014:04:29:00:00:00,5,2,2014:04:29:01:00:00,3.0,2014:04:29:01:30:00,3.0