文本处理 - 使用 cshell 和 awk 提取

文本处理 - 使用 cshell 和 awk 提取

我有一个很长的文件,在整个文件中随机重复包含以下几行

$CROSS_BEAM_PROPERTY_281
POINT,201656,,-41.0213,-1.00928
POINT,201657,,-37.8216,-4.15746
POINT,201658,,-5.40451,-51.3106
POINT,201659,,-4.24517,-52.0837
POINT,201660,,-1.74418,-53.1687
POINT,201661,,2.03505,-51.2474
SET3,9,POINT,201670,201683,THRU,201701,201682
PBMSECT,1501,150,CP
        OUTP=8,
        BRP=9,
        T=1.3,
        T(1)=[1.3,PT=(201656, 201657)],
        T(2)=[1.3,PT=(201657, 201658)],
$CROSS_BEAM_PROPERTY_109
POINT,201660,,-1.74418,-53.1687
POINT,201661,,2.03505,-51.2474
POINT,201662,,4.249589,-48.9936
POINT,201663,,7.70361,-48.5562
POINT,201664,,9.169905,-48.7962
POINT,201665,,30.79493,-53.7184
POINT,201666,,33.52191,-53.1064
POINT,201667,,27.54975,-45.6262
PBMSECT,1500,150,CP
        OUTP=6,
        BRP=7,
        T=1.3,
        T(1)=[1.3,PT=(201610, 201611)],
        T(2)=[1.3,PT=(201611, 201612)],

对于每个CROSS_BEAM_PROPERTY,我想将POINT的第四列和第五列提取为变量数组,以便我可以一次性对其进行进一步处理?如何使用 cshell awk 或 sed 提取它们?

编辑:只是一个概述,在文本文件中,有很多CROSS_BEAM_PROPERTY_XX并且POINT定义了 x 和 y 中的位置。上面的示例只是具有两个横梁属性的文件的片段。我想将CROSS_BEAM_PROPERTY_XX第四列保存到一个数组中。使用数组,我可以做一些进一步的计算来提取数组的最大值、最小值或总和值。

我设法提取所有第四列并使用下面的行对其进行总结。

cat $file | awk -F ',' '$1 == "POINT" {sum += $4} END {print sum}'

POINT但这是文本文件中所有条目的所有第四列的总和。它不会为每个分开CROSS_BEAM_PROPERTY_XX。除了总和之外,我还想确定第四列中每个值的最大值和最小值CROSS_BEAM_PROPERTY- 因此需要一个数组。

期望的输出:

-88.20171
113.280564

是否也可以获得第四列最大值的所需输出,如下所示?

2.03505
33.52191

答案1

 cat $file | awk -F "," '/^\$CROSS/,/^PBMSECT/{if($0~/CROSS/){v=$0};if($0~/^POINT/){p[v]+=$4}}END{for(i in p){print p[i]}}'

这将输出第一个请求的输出:

-88.20171
113.280564

对于您请求的第二个输出,将执行以下操作:

cat $file | awk -F "," '/^\$CROSS/,/^PBMSECT/{if($0~/CROSS/){v=$0};if($0~/^POINT/){if($4>p[v]){p[v]=$4}}}END{for(i in p){print p[i]}}'

您可以在输出中包含 cross_beam_property 以使输出数据更好

$ cat $file | awk -F "," '/^\$CROSS/,/^PBMSECT/{if($0~/CROSS/){v=$0};if($0~/^POINT/){p[v]+=$4}}END{for(i in p){printf("%s\t%f\n", i, p[i])}}'
$CROSS_BEAM_PROPERTY_281        -88.201710
$CROSS_BEAM_PROPERTY_109        113.280564

答案2

根据您的解释,我不确定您到底在寻找什么,但如果您想获得每POINT行的第四列和第五列,您可以轻松地使用以下方法来实现sed

sed -n -e 's/^POINT,[^,]*,[^,]*,//p' data.csv

这将从示例数据中生成以下输出:

-41.0213,-1.00928
-37.8216,-4.15746
-5.40451,-51.3106
-4.24517,-52.0837
-1.74418,-53.1687
2.03505,-51.2474
-1.74418,-53.1687
2.03505,-51.2474
4.249589,-48.9936
7.70361,-48.5562
9.169905,-48.7962
30.79493,-53.7184
33.52191,-53.1064
27.54975,-45.6262

如果要将这些数据放入数组中,可以使用过程替换,如下所示:

set array=`sed -n -e 's/^POINT,[^,]*,[^,]*,//p' data.csv`

然后您可以通过array变量访问这些数据,例如:

foreach point (${array})
echo ${point}
end

当然,你可以使用以下方法做同样的事情awk

awk 'BEGIN{FS=",";OFS=","}/^POINT/{print $4,$5}' data.csv

或者甚至只是使用grepand cut

cat data.csv | grep '^POINT' | cut -d, -f4,5

相关内容