awk在foreach循环中的两个关键字

时间:2013-12-06 16:55:46

标签: loops replace awk pattern-matching

我有一个文本文件,我想在特定关键字上循环,并找到该子组的另一个关键字。实际上,一旦它遍历特定​​关键字,我想找到第二个关键字的最后列出的条目,并将日期和时间更改为“12/31/2500 23:59:59”。

文本文件如下:

sta first keyword lat long depth
time date time
add
second keyword sensor type date time

sensor
add 
second keyword sensor type 10/31/2013 23:59:59
----------------------------------------------
sta first keyword lat long depth
time date time
add
second keyword sensor type date time

sensor
add 
second keyword sensor type date time 

所以我想遍历第一个关键字,找到文本文件中第二个关键字的最后一个条目,并将“第二个关键字传感器类型日期时间”行的日期时间更改为12/31 2500个数据当时23:59:59

我想用awk做这个,但是找不到好方法。任何人都可以帮助我或引导我朝着正确的方向前进吗?我对awk相对较新,仍然在学习和阅读有关语法结构的内容。

上面的预期输出将是:

sta first keyword lat long depth
time date time
add
second keyword sensor type date time

sta first keyword lat long depth
time date time
add 
second keyword sensor type 12/31/2500 23:59:59

请注意,可能不仅仅是上面显示的2个文本块。

我对循环的想法可能是以某种方式使用awk或使用foreach循环,所以     foreach i(第一个关键字)     awk #####

类似的东西,或只是与awk。整个文本块彼此相关联,因为存在不同的sta第一关键字条目。这些是我要拨打的电台名称。有意义还是需要更多解释?

进一步更新此问题: 这是我从帮助和我自己开发的另一个问题的第一部分(评论中有一个链接):

     awk -F '[ : ]' 'NR==FNR && /time/ { A[++N]=$2" "$3":"$4":"$5-01 }; NR==FNR { next }; /time/ 
     {    M++ }; M && ((M%2) == 1) && /close/ {  NF=3 ; $0=$0" "A[M+1]   } 1'
     "$piername"_comprehensive20"$year"_bfile.txt "$piername"_comprehensive20"$year"_bfile.txt  
     >> "$piername"_20"$year"_bfile.txt

这样做是从下一个站块定义中获取时间并将其置于前一个站块的关闭时间(两个闭合语句对于一个站块)并减去一秒。

为了澄清,每个电台块都包含2个密切的陈述,这些陈述并不像我希望的那样明确。所以上面的条目是一个站块,我又添加了一个,它可以是一个不同的站名,即WP00,然后是WP01。我想做的是使用最后一个站条目(包含2个关闭语句),使这两个关闭语句都为12/31/2500。我想用我的awk语句来维护我上面所做的事情,其中​​每个站的其余站块。

我希望这有助于澄清我的意思:)。

为了进一步更新问题,我想在Hakon的帮助下,这是解决方案:

awk -F '[ : ]' '
NR==FNR {
    if (/time/)
        A[++N]=$2" "$3":"$4":"($5-01)
    else if (/close/) {
        B[FNR]=0
        n1=n2;
        n2=FNR;
    }
    else if (/^sta EP/) {
        match($0,/^sta EP([0-9]*)/,a)
        snr=a[1]
        if (snr != prev) {
            B[n1]=1
            B[n2]=1
        }
        prev=snr
    }
    next
}

FNR==1 {
    B[n1]=1; B[n2]=1
}
/time/ {
    M++
}
/close/ {
    if (B[FNR])
        $0=$1" ""sta"" ""12/31/2013 23:59:59"
    else if ((M%2) == 0 || (M%2) == 1) {
        NF=3
        $0=$0" "A[M+1]
    }
}
{print}' file file 

我稍微修改了这个以尝试做一些不同的事情,我不可避免地想要使用脚本。但所有的作品都在那里。

1 个答案:

答案 0 :(得分:1)

来自您之前的帖子:awk/grep replace 2nd match after first match in text file while in foreach loop 我想你可能想要在下一个close关键字之前更改最后station? 然后你可以尝试类似的东西:

awk -f m.awk file file

其中file是您的输入文件,m.awk是:

FNR==NR {
    if (/^close/) {
        z[++k]=FNR
        if (k==3) {
            key=$4 FS $5
            b[z[1]]=key
            b[z[2]]=key
        }
        prev=FNR
    } else if (/^sta/) {
        a[prev]=1
        k=0
    }
    next
}
FNR==1 { a[prev]=1 }
{
    if (/^close/) {
        if (FNR in b)
          $0=$1FS$2FS$3FS b[FNR]
        if (a[FNR])
            $0=$1FS$2FS$3FS"12/31/2500 23:59:59"
    }
    print
}

例如,给定以下输入文件:

sta WP00 34.07335 -106.91932 1.43

close sensor trillium_240_2 10/23/2013 20:10:17
bla

close sensor trillium_120 10/28/2013 20:20:45

close sensor trillium_80 10/28/2013 20:30:17

close sensor trillium_60 10/28/2013 20:40:29

close sensor trillium_40 10/28/2013 20:50:10

sta WP01 34.07335 -106.91932 1.43

close sensor trillium_240_2 10/23/2013 20:10:17
bla
bla

close sensor trillium_120 10/28/2013 20:20:45

close sensor trillium_120 10/28/2013 20:20:45

close sensor trillium_80 10/28/2013 20:30:17

close sensor trillium_40 10/28/2013 20:50:10

并且运行awk -f m.awk file file会输出:

sta WP00 34.07335 -106.91932 1.43

close sensor trillium_240_2 10/28/2013 20:30:17
bla

close sensor trillium_120 10/28/2013 20:30:17

close sensor trillium_80 10/28/2013 20:30:17

close sensor trillium_60 10/28/2013 20:40:29

close sensor trillium_40 12/31/2500 23:59:59

sta WP01 34.07335 -106.91932 1.43

close sensor trillium_240_2 10/28/2013 20:20:45
bla
bla

close sensor trillium_120 10/28/2013 20:20:45

close sensor trillium_120 10/28/2013 20:20:45

close sensor trillium_80 10/28/2013 20:30:17

close sensor trillium_40 12/31/2500 23:59:59

更新

根据以下评论中的讨论,我提供了一个新版本:

NR==FNR {
    if (/time/)
        A[++N]=$2" "$3":"$4":"($5-1)
    else if (/close/) {
        B[FNR]=0
        n1=n2;
        n2=FNR;
    }
    else if (/^sta WP/) {
        match($0,/^sta WP([0-9]*)/,a)
        snr=a[1]
        if (snr != prev) {
            B[n1]=1
            B[n2]=1
        }
        prev=snr
    }
    next
}

FNR==1 {
    B[n1]=1; B[n2]=1
}
/time/ {
    M++
}
/close/ {
    if (B[FNR]) {
        $0=$1" "$2" "$3" 12/31/2500 23:59:59"
    }
    else if (M%2) {
        NF=3
        $0=$0" "A[M+1]
    }
}
{print}

使用输入执行此操作:

sta WP00 34.07335 -106.91932 1.43
time 10/23/2013 20:10:17
close sensor trillium_240_2 10/23/2013 20:10:17
add
close sensor trillium_120 10/23/2013 20:10:35
sta WP00 34.07335 -106.91932 1.43
time 10/28/2013 20:20:28
close sensor trillium_240_2 10/28/2013 20:20:28
close sensor trillium_120 10/28/2013 20:20:45
sta WP00 34.07335 -106.91932 1.43
time 10/28/2013 20:22:30
close sensor trillium_240_2 10/28/2013 20:24:28
close sensor trillium_120 10/28/2013 20:25:45
sta WP01 34.07335 -106.91932 1.43
time 10/23/2013 20:30:17
close sensor trillium_240_2 10/23/2013 20:10:17
add
close sensor trillium_120 10/23/2013 20:10:35
sta WP01 34.07335 -106.91932 1.43
time 10/28/2013 20:40:28
close sensor trillium_240_2 10/28/2013 20:20:28
close sensor trillium_120 10/28/2013 20:20:45

产生输出:

sta WP00 34.07335 -106.91932 1.43
time 10/23/2013 20:10:17
close sensor trillium_240_2 10/28/2013 20:20:27
add
close sensor trillium_120 10/28/2013 20:20:27
sta WP00 34.07335 -106.91932 1.43
time 10/28/2013 20:20:28
close sensor trillium_240_2 10/28/2013 20:20:28
close sensor trillium_120 10/28/2013 20:20:45
sta WP00 34.07335 -106.91932 1.43
time 10/28/2013 20:22:30
close sensor trillium_240_2 12/31/2500 23:59:59
close sensor trillium_120 12/31/2500 23:59:59
sta WP01 34.07335 -106.91932 1.43
time 10/23/2013 20:30:17
close sensor trillium_240_2 10/23/2013 20:10:17
add
close sensor trillium_120 10/23/2013 20:10:35
sta WP01 34.07335 -106.91932 1.43
time 10/28/2013 20:40:28
close sensor trillium_240_2 12/31/2500 23:59:59
close sensor trillium_120 12/31/2500 23:59:59