搜索由shell重复多次重复的单词

时间:2017-03-21 04:47:38

标签: bash shell awk

我在每行重复多次重复“TEMPO”字样的文件。 例如:

(TAF HECA 312300Z 0100/0206 32008KT 6000 NSC TEMPO 0100/0107 VRB03KT 4000HZ PROB40 TEMPO 0101/0106 2000BR BECMG 0109/0111 35010KT 9999 SCT025=) 

我想逐个搜索(TEMPO)以制作条件:

如果第1个(TEMPO)后的小时> =第1个6个小时停止并且如果没有完成读取并搜索第2个(TEMPO)。我的脚本是:

   #!/bin/sh
      cat taf2 | while read line 
    do
    ihour1=`echo $line |cut -d "Z" -f2 | awk '{ print substr($0,2,4) }'`
    lhour1=`echo $line |cut -d "Z" -f2 | awk '{ print substr($0,7,4) }'`
    l6hour1=`expr $ihour1 + 6`
    printf -v l6hour1 "%04d" $l6hour1 ; echo $l6hour1
    line2=`echo $line | sed "s:Z ${ihour1}/${lhour1}:Z      ${ihour1}/${l6hour1}:g"`
    #echo $line2
    # search for TEMPO
    ihour2=`echo $line2 |awk '{for (I=1;I<=NF;I++) if ($I == "TEMPO")  {val[++c]=substr($(I+1),1,4);{print $(I+1)};}}'|awk '{print substr($0,1,4)}'`
    lhour2=`echo $line2 |awk '{for (I=1;I<=NF;I++) if ($I == "TEMPO") {print  $(I+1)};}'|awk '{print substr($0,6,4)}'`
    ##
    count_tempo=`echo $ihour2 |wc -w`
    for cc in {1..$count_tempo};do
    echo $ihour2 $val[$cc] 
    if [ $ihour2 -ge $l6hour1 ]; then
    fline=`echo $line2 | sed "s: TEMPO.*::g"`
    echo no
    else
    fline=`echo $line2| sed "s:TEMPO ${ihour2}/${lhour2}:TEMPO  ${ihour2}/${l6hour1}:g"`
    echo yes
    fi
    echo $fline "=" >>ttt
    done
    done
    ####

我想绕过一些TEMPO循环,单独读取第一个,然后可以转到下一个或不是。 谢谢你的帮助。

3 个答案:

答案 0 :(得分:0)

  

首先,尝试打印与TEMPO对应的所有小时值 -

awk '{for (I=1;I<=NF;I++) if ($I == "TEMPO") {print substr($(I+1),1,4)}}' f
  

如果你想在TEMPO之后搜索特定的小时值后停止,   检查下面的输入文件和解决方案 -

 cat f ###added one more TEMPO with 0110/0111 in last

 TAF HECA 312300Z 0100/0206 32008KT 6000 NSC TEMPO 0100/0107 VRB03KT 4000HZ PROB40 TEMPO 0101/0106 2000BR BECMG 0109/0111 08KT 6000 NSC TEMPO 0110/0111
  

目前,我们有三个TEMPO值 -

awk '{for (I=1;I<=NF;I++) if ($I == "TEMPO") {a[$(I+1)]++}} END {for(i in a) print substr(i,1,4)}' f
0110
0101
0100
  

现在,如果我想在搜索0101之后停下来,那么我将在下面使用   命令 -

awk '{for (I=1;I<=NF;I++) if ($I == "TEMPO") {a[$(I+1)]++}} END {for(i in a) if(substr(i,1,4) != "0101") {print substr(i,1,4)} else {print substr(i,1,4);exit}}' f
0110
0101

答案 1 :(得分:0)

在GNU awk(正则表达式FS)中:

$ awk -F"[ /]" -v certain_value="0100" '            # set FS to " " or "/"
/TEMPO/{                                            # all records with TEMPO 
    for(i=1;i<=(NF-1);i++)                          # iterate all but last field
        if($i=="TEMPO" && $(i+1)==certain_value) {  # if match
            print $(i+1)                            # output certain_value
            next                                    # move to process next record
        }
}'  file
0100

如果每个记录都有TEMPO,您可以从代码中删除以下行:

/TEMPO/ {
}          # basically either will do

答案 2 :(得分:0)

您的错误在我的Debian(GNU Awk 4.1.4)中无法重现 此外,您不必将awk管道传输到另一个awk - 您可以直接在同一个awk中应用substr。

CASE WHEN DATENAME(WeekDay, dt.start_time) IN ('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday') 
            and CAST(dt.start_time as time) >= '07:00:00' AND CAST(dt.start_time as time) <= '16:59:59' THEN '103856' --WEEKDAY
     WHEN DATENAME(WeekDay, dt.start_time) IN ('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday') 
            and CAST(dt.start_time as time) >= '17:00:00' AND CAST(dt.start_time as time) <= '21:59:59' THEN '103857' --WEEKDAY-EVENING
    WHEN DATENAME(WeekDay, dt.start_time) IN ('Saturday', 'Sunday') THEN 'WEEKEND'  
END 

在上面的测试中,我将TEMPO的值存储在数组$ a="(TAF HECA 312300Z 0100/0206 32008KT 6000 NSC TEMPO 0100/0107 VRB03KT 4000HZ PROB40 TEMPO 0101/0106 2000BR BECMG 0109/0111 35010KT 9999 SCT025=)" $ awk '{for (I=1;I<=NF;I++) if ($I == "TEMPO") {val[++c]=substr($(I+1),1,4);print val[c]}}' <<<"$a" 0100 0101 中。 val将找到第一个找到的TEMPO值,val[1]将保留第二个找到的速度值,等等。

然后你可以循环遍历这个数组(即length(val)返回数组val的长度(元素数)),你可以构建自己的条件检查。