Linux 在while read循环bash中从第4行获取变量

Linux 在while read循环bash中从第4行获取变量,linux,bash,text,while-loop,Linux,Bash,Text,While Loop,使用此方案获得一个txt文件:(仅10k行中的8行) 我需要做的是得到a变量的“分数”,它总是在第4行,如果它的值大于“6.0”,上面的3行需要保存 因此,将示例作为输入,当脚本运行时,输出如下: London: 605 London_average: 30 London_lenght: 30 score: 6.3 我已经考虑了4行的“while..read”循环,但我不知道如何继续。 带标签的bash以及perl解决方案都很受欢迎。以下awk可能会对您有所帮助: awk '{a[FNR]=$

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

我需要做的是得到a变量的“分数”,它总是在第4行,如果它的值大于“6.0”,上面的3行需要保存

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

London: 605
London_average: 30
London_lenght: 30
score: 6.3
我已经考虑了4行的“while..read”循环,但我不知道如何继续。
带标签的bash以及perl解决方案都很受欢迎。

以下
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
解决方案:

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

样本输出:

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

奖金
grep
解决方案:

awk '$1=="score:" && $2 > 6{ print r1 r2 r3 $0 }{ r1=r2; r2=r3; r3=$0 ORS }' file
grep -B3 '^score: [6-9]' file

如果模式
得分:
行作为第二行,带有4行部分/块:

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

使用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 '
{
    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

另一个用于使用缓冲和打印的reqular awk:

$ 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
解释:

$ 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 '
{
    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

我个人建议使用awk。到目前为止,您编写了哪些代码?请稍等片刻,阅读$line1$line2$line3$line4。您认为如何实现awk命令来保留上面的3行?如果分数为21怎么办?还是-7?这些可能是边缘情况,但我们不确定分数是否总是在
[0-10]中[
range@Aserre相应地修改正则表达式。这就是为什么我清楚地说明了对分数的期望值。第一个不好,因为例如,如果值为120,则不符合条件。@当我知道分数的要求时,撕碎它是好的,就像在回答和评论中提到的那样。但这更像是对我自己的测试如何使用
RT
和正则表达式(引用Marty McFly的话:我想你们还没准备好。但你们的孩子会喜欢的!)JamesBrown you's awk解决方案很有效。我试着在一个由长行组成的文件上运行它(每三行大约有10k个字符)而且,不知道为什么,它有时会跳过这些行。对于巨大的txt文件有什么已知的问题吗?回答也很好。你能用两行解释一下“FNR”到底是什么吗这里有吗?我已经读过用于比较两组文件的行。@shread现在也将添加解释。我必须注意,这种方法将把整个文件映射到内存中(将每个记录放入数组)@RavinderSingh13您的示例脚本在验证条件的脚本之前打印行。如果我想在之后打印行呢?我已经尝试使用{print a[FNR++1]RS a[FNR++2]}但是,由于某些原因,当使用加号而不是减号时,它只打印空行。@Shred,尝试使用
FNR+1
FNR+2
请不要在那里使用
++
,让我知道它是如何运行的。只是想知道..如果“分数”:是否在第二行?我正在尝试修改您提供的脚本,但无法确定如何将记录正确地重新分配给变量。我已尝试..{print r1$0 r3 r4}{r1=$0;$0=r3;r3=r4 ORS}'。但它只打印“score…”后的前两行因此,它似乎无法识别其他变量。@Shred,你可以提出一个新问题来处理新的条件。这是没有用的。只是问一个方法,用你的方法将变量处理到第二行。@Shred,我应该观察一个新的输入数据。我如何知道你如何交换其余的行?复制了pastebin.com上的输入,到期日限制评论的字符。