![텍스트 처리 - cshell 및 awk를 사용한 추출](https://linux55.com/image/121577/%ED%85%8D%EC%8A%A4%ED%8A%B8%20%EC%B2%98%EB%A6%AC%20-%20cshell%20%EB%B0%8F%20awk%EB%A5%BC%20%EC%82%AC%EC%9A%A9%ED%95%9C%20%EC%B6%94%EC%B6%9C.png)
파일 전체에서 무작위로 반복되는 다음 줄을 포함하는 매우 긴 파일이 있습니다.
$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를 사용하여 추출하는 방법은 무엇입니까?
편집: 단지 개요입니다. 텍스트 파일에는 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
아니면 그냥 grep
and 를 사용하세요 cut
:
cat data.csv | grep '^POINT' | cut -d, -f4,5