在一段时间内从第4行获取变量bash

时间:2018-02-20 09:19:03

标签: linux bash text while-loop

使用此方案获得了一个txt文件:(仅10k行中的8个)

Paris: 405
Paris_average: 20
Paris_lenght: 30
score: 5.4
London: 605
London_average: 30
London_lenght: 30
score: 6.3

我需要做的是获得"得分"变量总是在第4行,并且其值大于" 6.0",上面的3行需要保存。

因此,将示例作为输入,当脚本运行时,输出如下:

London: 605
London_average: 30
London_lenght: 30
score: 6.3

我已经考虑过" while..read"循环为4行,但我不知道如何前进。 标记为bash,但perl解决方案也很受欢迎。

3 个答案:

答案 0 :(得分:3)

awk 解决方案:

awk '$1=="score:" && $2 > 6{ print r1 r2 r3 $0 }{ r1=r2; r2=r3; r3=$0 ORS }' file
  • $1=="score:" && $2 > 6 - 检查主要条件; $1$2分别是第1和第2个字段
  • r1=r2; r2=r3; r3=$0 ORS - 连续重新分配 3个后续记录中的每一个到变量r3 - > r2 - > r1
  • print r1 r2 r3 $0 - 打印相关的得分行以及之前的3条记录

示例输出:

London: 605
London_average: 30
London_lenght: 30
score: 6.3

奖金 grep 解决方案:

grep -B3 '^score: [6-9]' file

如果模式score:行作为带有4行部分/块的第2行:

grep -B1 -A2 '^score: [6-9]' file

答案 1 :(得分:2)

关注awk可能对您有所帮助:

awk '{a[FNR]=$0;} /score:/ && $2>6 && FNR!=1{print a[FNR-3] RS a[FNR-2] RS a[FNR-1] RS $0}'   Input_file

现在添加非同一种内衬形式:

awk '
{
  a[FNR]=$0
}
/score:/ && $2>6 && FNR!=1{
  print a[FNR-3] RS a[FNR-2] RS a[FNR-1] RS $0
}
'   Input_file

<强> 说明:

awk '
{
  a[FNR]=$0                                    ##Creating an array named a whose index is FNR(current line) and value is assigned as current line to it.
}
/score:/ && $2>6 && FNR!=1{                    ##Checking condition here where checking if a line is having string score: in it and 2nd field is greater than 6 and line number is NOT one then do following:
  print a[FNR-3] RS a[FNR-2] RS a[FNR-1] RS $0 ##Printing the value of a[FNR-3](3rd line from current line), RS(record seprator) a[FNR-2](2nd line from current line) a[FNR-1](prevoius line of current line)
}
'   Input_file                                 ##Mentioning Input_file name here too.

答案 2 :(得分:1)

使用GNU awk并期望得分为[0.9].[0-9]且小于10.0:

$ gawk 'BEGIN{RS="\nscore: ...\n"}RT~/[6789]\./{printf "%s%s",$0,RT}' file
London: 605
London_average: 30
London_lenght: 30
score: 6.3

说明:

$ gawk '
BEGIN {
    RS="\nscore: ...\n"   # record separator is the score line
}
RT~/[6789]\./ {           # if the score starts with a digit 6-9
    printf "%s%s",$0,RT   # output the record
}' file

使用缓冲和打印的另一个awk(s):

$ awk '{b=b $0 (NR%4?ORS:"")}!(NR%4){if($2>6)print b;b=""}'  file
London: 605
London_average: 30
London_lenght: 30
score: 6.3

说明:

$ awk '
{
    b=b $0 (NR%4?ORS:"")  # buffer records
}
!(NR%4) {                 # on every 4th record
    if($2>6)              # if condition met
        print b           # print buffer
    b=""                  # reset buffer
}'  file