awk에서 가장자리 값을 얻는 더 좋은 방법

awk에서 가장자리 값을 얻는 더 좋은 방법

일부 정보를 수집하여 테이블에 출력하는 것이 주요 목적인 스크립트가 있습니다. 주요 부분은 awk 스크립트입니다:

awk '
    { 
      # do some stuff, including calculating dwt
      printf(format, a, b, c, d)
    }
    END {
      # pass on dwt
    }
' inputfile

awk의 주요 목적은 테이블을 생성하고 표시하는 것입니다. 그러나 이는 또한 기본 스크립트의 다른 곳에서 필요한 부가 값을 계산하고 dwt테이블 출력을 중단하지 않고 이를 전달할 수 있는 가장 좋은 방법을 찾으려고 노력하고 있습니다.

나는 이를 수행하는 두 가지 방법을 알고 있습니다.

  1. 값을 임시 파일에 저장한 END { print dwt > "tempfile" }다음 외부에서 읽습니다 read dwt <tempfile; rm -f tempfile. 그러나 기존 파일이 손상되지 않도록 여기에 표시된 것보다 더 주의를 기울인다고 해도 나는 여전히 이것을 피하는 것을 선호합니다. 다른 것이 없다면 작업이 잘못된 시간에 중단되었기 때문에 임시 파일이 남아 있는 것을 원하지 않습니다.
  2. 또한 값을 표준 출력으로 보내지만 태그가 지정됩니다. stdout을 다음 루틴으로 파이프하여 태그가 지정된 출력을 적절하게 캡처하고 지시하지만 나머지는 보냅니다.
    awk '
       ...
        END { 
           print "dwt:" dwt 
        }
     ' inputfile | while read line; do
        if [[ $line = dwt:* ]]; then
           dwt="${line#dwt:}"
        else
           echo "$line"
        fi
     done

그러나 이것은 인위적이고 우아하지 않은 것 같습니다.

누군가가 더 좋은 방법을 알고 있는지 궁금합니다. 다른 파일 설명자를 사용해 보았지만 지금까지는 성공하지 못했습니다. 파일 설명자에서 정보를 가져와 표준 출력을 손상시키지 않고 dwt 환경 변수에 넣는 방법을 찾지 못했습니다.

답변1

다음은 기술입니다.

  • END의 stdout에 dwt를 인쇄합니다.
  • awk 출력을 배열로 캡처
  • 쉘 프로세스에서 배열의 마지막 요소를 변수로 추출합니다.
  • 나머지 배열을 인쇄합니다.
$ seq 5 > inputfile
$ readarray -t output < <(
    awk '
        { print "table", $0; dwt += $1 }
        END {print dwt}
    ' inputfile
)
$ dwt=${output[-1]}
$ echo "dwt = $dwt"
dwt = 15
$ unset output[-1]
$ printf "%s\n" "${output[@]}"
table 1
table 2
table 3
table 4
table 5

좋아, ksh가 없으면 readarray쉘 스크립트는 다음과 같을 것이다:

awk '
    { 
      # do some stuff, including calculating dwt
      printf(format, a, b, c, d)
    }
    END {
      # pass on dwt
      print dwt
    }
' inputfile  |&
# ...........^^

typeset -a output
while IFS= read -r -p line; do output+=( "$line" ); done
# .................^^

dwt=${output[-1]}
unset output[-1]
printf "%s\n" "${output[@]}"

# do stuff with $dwt ...

내 ksh93 매뉴얼 페이지에서:

이 기호는 |&이전 파이프가 비동기적으로 실행되도록 하고 상위 쉘과 양방향 파이프를 설정합니다. 결과 파이프의 표준 입력 및 출력은 설명된 -p 내장 명령의 옵션을 사용하여 상위 쉘에서 쓰고 읽을 수 있습니다. read나중에 .print

답변2

약간 서투르지만 awk평가 시 쉘 명령을 인쇄 할 수 있습니다 ksh.

eval $( echo -e 1\\nA\\n2\\n3\\n4 |
  awk  'NR == 1 {printf"%s%s%s;","export var1=",$0, "\n"}
        NR > 2 {printf"%s%s%s;","echo -e '", $0 , "'\n" }'
)

산출:

2
3
4

$ echo $var1
1

그러나 라인별 쉘 평가는 가장 간단하지 않을 수 있으며 특정 문자열의 경우 에코는 흥미로운 결과를 제공할 수 있습니다. 이러한 위험을 인지하시기 바랍니다! , 그러나 하드 참조는 다음을 피해야 합니다.

eval $( echo -e 1\\nA\\n2\\n3\\n4 |
  awk  'NR == 1 {printf"%s%s%s;","export var1=",$0, "\n"}
        NR > 2 {printf"%s%s%s;","echo -e \x27", $0 , "\x27\n" }'
)

관련 정보