줄의 opcode(명령어)를 기반으로 ADD 또는 SUB 번호

줄의 opcode(명령어)를 기반으로 ADD 또는 SUB 번호

awk입력 파일의 행에 대해 요청한 내용에 따라 더하거나 뺄 수 있는 스크립트를 어떻게 작성할 수 있습니까 ? 나는 하나의 스크립트에서 덧셈이나 뺄셈만 수행하고 둘 중 하나는 수행하지 않는 방법을 알아냈습니다.

예를 들어 다음과 같은 입력을 원합니다.

ADD 5,10,20
SUB 30,5,20

다음 출력을 생성합니다.

35
-55

이것이 내가 지금까지 쓴 내용이다:

#!/bin/awk 
BEGIN {
    FS=","
}

{
    for(i=1;i<=NF;i++) 
        sum+=$i; 
    print sum; sum=0}

하지만 분명히 덧셈만 할 뿐 모든 숫자를 얻지는 못하는 것 같습니다.

답변1

몇 가지 팁:

  • 필드 구분 기호로 공백이나 쉼표를 사용합니다.FS = "[ ,]"
  • 그런 다음 당신이 했던 것처럼 숫자를 추가하세요.i = 2
  • 첫 번째 필드가 이면 SUB합계에 -1을 곱합니다.

답변2

다음은 곱해진 값(1 또는 -1)을 유지하기 위해 연관 배열을 사용하여 Glenn Jackman의 알고리즘을 구현하는 한 가지 방법입니다.

$ awk -F ',|[[:blank:]]+' '
    BEGIN {
      mult["ADD"] =  1;
      mult["SUB"] = -1;
    };

    $1 ~ /^(ADD|SUB)$/ {
      sum = 0;
      for (i=2; i <= NF; i++) { sum += $i };
      print sum * mult[$1];
    }' input.txt
35
-55

sum=$2이는 또한 "MULT", "DIV" 또는 "EXP"( for 루프를 시작하는 대신 사용하는)와 같은 다른 키워드를 추가하기 위한 프레임워크의 시작을 제공합니다 .i=3i=2

답변3

$ awk -F'[ ,]' '{sum=0; for (i=2; i<=NF; i++) sum+=$i; print ($1=="ADD" ? 1 : -1) * sum}' file
35
-55

예를 들어 ADD 및 SUB보다 더 많은 작업을 지원해야 하는 경우:

$ cat file
ADD 5,10,20
SUB 30,5,20
MULT 2,3,4
DIV 20,2,2

GNU awk를 사용하여 지원하려는 각 작업에 대한 함수를 정의하고 간접적으로 호출할 수 있습니다.

$ cat tst.awk
function ADD(n)  { sum += n }
function SUB(n)  { sum -= n }
function DIV(n)  { if (n==0) { printf "%s[%d]: Divide by zero error in %s\n", FILENAME, FNR, $0 | "cat>&2"; exit 1 } sum /= n }
function MULT(n) { sum *= n }

BEGIN { FS="[ ,]" }
{
    op = $1
    sum = (op=="SUB" ? -1 : 1) * $2
    for (i=3; i<=NF; i++) {
        @op($i)
    }
    print sum
}

$ awk -f tst.awk file
35
-55
24
5

제공한 입력에서 원하는 출력을 얻으려면 특수한 경우 "SUB"를 사용해야 했습니다. 왜냐하면 나머지 입력과 다르게 처리되기 때문입니다(즉, 모든 숫자를 더하거나 곱셈/나눗셈을 더하는 대신 모든 숫자를 0에서 뺍니다). SUB 줄의 첫 번째 숫자가 -30또는 0이면 30모든 작업을 정확히 동일한 방식으로 처리할 수 있습니다. 예를 들면 다음과 같습니다.

$ cat file
ADD 5,10,20
SUB 0,30,5,20
MULT 2,3,4
DIV 20,2,2

$ cat tst.awk
function ADD(n)  { sum += n }
function SUB(n)  { sum -= n }
function DIV(n)  { if (n==0) { printf "%s[%d]: Divide by zero error in %s\n", FILENAME, FNR, $0 | "cat>&2"; exit 1 } sum /= n }
function MULT(n) { sum *= n }

BEGIN { FS="[ ,]" }
{
    op = $1
    sum = $2
    for (i=3; i<=NF; i++) {
        @op($i)
    }
    print sum
}

$ awk -f tst.awk file
35
-55
24
5

관련 정보