텍스트 처리 - 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하시겠습니까 ? POINTcshell awk 또는 sed를 사용하여 추출하는 방법은 무엇입니까?

편집: 단지 개요입니다. 텍스트 파일에는 x와 y에 많은 정의된 위치가 CROSS_BEAM_PROPERTY_XX있습니다 . POINT위의 예는 두 개의 빔 속성이 있는 파일의 일부입니다. 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

관련 정보