我有一组数据,其中包含地震波传播时间及其相应信息(即产生波的源以及该波沿着传播到达每个地震检波器的时间)。我正在尝试格式化数据以适合我的代码,以便使用数据进行一些断层扫描,但我对 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”行有数百行,并且将其包含在问题中似乎过多。为了便于阅读,我删除了大部分数据。
一个简单的方法是向后读取文件。
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