text processing - Extraindo usando cshell e awk

0

Eu tenho um arquivo longo contendo as seguintes linhas repetidamente aleatoriamente em todo o arquivo

$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)],

Para cada CROSS_BEAM_PROPERTY , gostaria de extrair a quarta e quinta colunas do POINT como uma matriz variável para que eu possa processar mais de uma vez? Como faço para extraí-los usando o cshell awk ou sed?

Editar: Apenas uma visão geral, no arquivo de texto, há muito CROSS_BEAM_PROPERTY_XX e o POINT define a localização em x e y. O exemplo acima é apenas um trecho do arquivo com duas propriedades de cross beam. Eu gostaria de salvar para cada CROSS_BEAM_PROPERTY_XX a quarta coluna em uma matriz. Com o array, eu poderia fazer mais alguns cálculos para extrair o valor máximo, o valor mínimo ou o valor da soma do array.

Consegui extrair toda a quarta coluna e resumir usando a linha abaixo.

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

Mas isso soma toda a quarta coluna de todas as entradas POINT no arquivo de texto. Não separa para cada CROSS_BEAM_PROPERTY_XX . Além da soma, gostaria também de identificar o valor max e min na quarta coluna para cada CROSS_BEAM_PROPERTY - daí a necessidade de um array.

Saída desejada:

-88.20171
113.280564

Também é possível obter a saída desejada para o máximo da quarta coluna como abaixo?

2.03505
33.52191
    
por nabilishes 13.11.2017 / 00:53

2 respostas

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]}}'

Isso gera a primeira saída solicitada:

-88.20171
113.280564

E para a segunda saída que você pediu, o seguinte fará:

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]}}'

Você poderia incluir o cross_beam_property na saída para tornar os dados de saída mais agradáveis

$ 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
    
por 16.11.2017 / 03:52
0

Não sei exatamente o que você está procurando com base na sua explicação, mas se você quiser obter a quarta e a quinta coluna de cada POINT row, poderá fazer isso facilmente com sed :

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

Isso produz a seguinte saída dos seus dados de exemplo:

-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

Se você quiser colocar esses dados em uma matriz, você pode usar a substituição de processos da seguinte forma:

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

Você pode acessar esses dados por meio da variável array , por exemplo:

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

Claro que você poderia fazer o mesmo usando awk :

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

Ou até mesmo usando grep e cut :

cat data.csv | grep '^POINT' | cut -d, -f4,5
    
por 13.11.2017 / 04:27