awk
여기 초보자입니다.
두 개의 데이터 열이 있고 delta(y)/delta(x)로 제공되는 성장률을 계산한다고 가정합니다. awk
스크립트에서 이 작업을 어떻게 수행합니까 ? 지금까지 배운 내용은 한 줄씩 작업하는 것뿐이어서 여러 줄을 처리하는 방법을 잘 모르겠습니다.
참고: N개의 데이터 포인트가 있다고 가정하면 N-1개의 기울기/속도 값을 얻게 됩니다.
예:
입력하다
x y 2 4 3 5 4 7
산출
Slope - 1 2
이것이 awk
최선의 선택입니까? 아니면 다른 도구가 더 나은가요?
답변1
변수를 사용하여 한 행에서 다음 행으로 기억해야 하는 데이터를 저장합니다.
출력의 N+1 행은 입력의 N 및 N+1 행을 기반으로 계산되므로 이전 행의 내용을 저장하려면 변수가 필요합니다. 행당 두 개의 필드가 있으므로 각 필드에 하나의 변수를 사용하십시오.
행 1과 2는 특별하게 처리됩니다(머리글 행, 데이터 부족). 특수 변수를 테스트하여 특정 줄 번호를 일치시킬 수 있습니다 NR
. 이 지시문을 사용 next
하면 현재 행의 나머지 처리를 건너뜁니다.
이 프로세스는 매우 간단하므로 변수를 사용하여 이전 줄의 내용을 나타내는 것으로 충분합니다. 현재 라인을 처리한 후, 이전 라인을 처리할 때 설정한 변수를 이용하여 현재 라인의 내용을 변수에 저장합니다.
NR == 1 { print "Slope"; next; }
NR == 2 { print "-"; }
NR >= 3 { print ($2 - y) / ($1 - x) }
NR >= 2 { x = $1; y = $2; }
awk는 각 입력 줄에 대한 코드를 차례로 실행하고 각 중괄호 그룹 앞의 표현식은 해당 그룹을 실행하기 위한 조건이므로 이는 다음 의사 코드와 동일합니다.
for each line {
NR = current line number;
$1 = first field; $2 = second field;
if (NR == 1) { print "Slope"; next; }
…
}
또는 이전 행의 데이터와 현재 행의 데이터 모두에 이름을 지정하면 코드를 더 읽기 쉽게 찾을 수 있습니다. 현재 행 처리가 끝나면 데이터가 "현재" 변수에서 "이전" 변수로 전송됩니다.
NR == 1 { print "Slope"; next; }
NR == 2 { print "-"; }
NR >= 2 { current_x = $1; current_y = $2; }
NR >= 3 { print (current_y - previous_y) / (current_x - previous_x) }
NR >= 2 { previous_x = current_x; previous_y = current_y; }
답변2
$ awk 'NR==1 { print; next; }; '\
' NR==2 { former_x=$1; former_y=$2; $3="-"; print; next; };'\
' { $3=($2-former_y)/($1-former_x); print; former_x=$1; former_y=$2; }' input
x y Slope
2 4 -
3 5 1
4 7 2
첫 번째 줄은 있는 그대로 인쇄됩니다.
다음 행 모두에서 다음 행의 계산에 사용할 수 있도록 x
열에 값을 저장해야 합니다 . y
2번째 줄은 아직 계산할 것이 없기 때문에 특별히 취급됩니다.
다음 모든 행에서 비율을 계산하고 이를 행에 새 필드로 추가하고 행을 인쇄하고 행 값을 저장합니다.
답변3
귀하의 입력이 다음과 같다고 가정합니다.
x y
2 4
3 5
4 7
4 8
그 다음에
awk 'NR==1{print $0" Slope"; getline}
{dx=($1-xold); dy=($2-yold);$3=(xold&&dx!=0)?dy/dx:"-"; xold=$1; yold=$2; print}' file
당신을 위한
x y Slope
2 4 -
3 5 1
4 7 2
4 8 -
설명 -o
awk 'NR==1{print $0" Slope"; getline}
첫 번째 레코드/행인 경우 NR==1
추가 헤더와 함께 인쇄하고 다음 줄로 이동합니다.getline
{dx=($1-xold); dy=($2-yold);
계산 dx
및 병합dy
$3=(xold&&dx!=0)?dy/dx:"-";
초기화된 경우 xold
(이 테스트 이후에만 라인 2에서 발생하므로 라인 2에서만 실패함) dx!=0
(div 0 오류 없음) $3=dy/dx
else$3="-"
xold=$1; yold=$2;
xold
그런 다음 합계 yold
값을 해당 레코드/행의 현재 x 및 y로 업데이트합니다.
print}' file
그런 다음 전체 레코드/라인을 인쇄합니다(새 레코드 포함 $3
).