有没有办法使用 awk 来计算 2 个标志之间的行数并将该数字输入到特定字段中?

问题描述 投票:0回答:1

我有一组数据,其中包含地震波传播时间及其相应信息(即产生波的源以及该波沿着传播到达每个地震检波器的时间)。我正在尝试格式化数据以适合我的代码,以便使用数据进行一些断层扫描,但我对 awk 还比较陌生。我现在需要将每个镜头/源的接收器数量插入到镜头/源信息行中,但每次的数量都是可变的。有没有办法让 awk 计算行数并将其插入到正确的字段中?

我的数据格式如下。

记录源/镜头的每一行:

s 0.01 0 0 -1 0

源/镜头信息后面的所有其他行:

r 0.1 0 0 1.218 0.01
r 0.15 0 0 1.214 0.01
r 0.2 0 0 1.213 0.01

我可以使用“s”作为镜头行的标志,我想计算每个源/镜头的“r”行数,并将该数字插入相应的“s”行。

每条“s”线的“r”线数量差异很大。

生成的代码应如下所示:

s 0.01 0 **3** -1 0
r 0.1 0 0 1.218 0.01
r 0.15 0 0 1.214 0.01
r 0.2 0 0 1.213 0.01
s 1.01 0 **5** -1 0
r 0.05 0 0 1.159 0.01
r 0.1 0 0 1.127 0.01
r 0.15 0 0 1.106 0.01
r 0.2 0 0 1.115 0.01
r 0.25 0 0 1.107 0.01

计数的行数应位于每个“s”行的第四列(此处为星号)。

我使用 awk 的经验仅限于重新排列/索引列,所以我真的不知道从哪里开始。我尝试过使用 awk 进行谷歌搜索,但是很难找到与我的具体情况实际相关的 awk 问题的答案(因此我决定自己问它)。

我也是使用 stackoverflow 的新手,所以如果我需要包含更多示例数据,请告诉我。我的数据大约包含 4000 行。

编辑:所需结果的数据与我的数据示例略有不同的原因是因为每个“s”行有数百行,并且将其包含在问题中似乎过多。为了便于阅读,我删除了大部分数据。

awk counting reformatting
1个回答
0
投票

一个简单的方法是向后读取文件。

  • 每当您看到
    r
    线时,就增加计数器
  • 每当您看到
    s
    线时,请替换计数器并重置它

然后反转结果:

tac input |
awk '
    /^r/ { n++ }
    /^s/ { $4=n; n=0 }
         { print }
' |
tac > output

您可以向前读取文件,但这涉及维护状态:

awk '
    /^s/ {
        # this prints the *previous* group of lines
        if (NR>1)
            print c1,c2,c3, n, c5,c6, r

        # save s columns, initialise n counter and r string
        c1=$1; c2=$2; c3=$3; n=0; c5=$5; c6=$6; r=""
    }
    /^r/ {
        n++
        r = r RS $0
    }
    END {
        # print final group
        print c1,c2,c3, n, c5,c6, r
    }
' input >output
© www.soinside.com 2019 - 2024. All rights reserved.