일부 정보를 수집하여 테이블에 출력하는 것이 주요 목적인 스크립트가 있습니다. 주요 부분은 awk 스크립트입니다:
awk '
{
# do some stuff, including calculating dwt
printf(format, a, b, c, d)
}
END {
# pass on dwt
}
' inputfile
awk의 주요 목적은 테이블을 생성하고 표시하는 것입니다. 그러나 이는 또한 기본 스크립트의 다른 곳에서 필요한 부가 값을 계산하고 dwt
테이블 출력을 중단하지 않고 이를 전달할 수 있는 가장 좋은 방법을 찾으려고 노력하고 있습니다.
나는 이를 수행하는 두 가지 방법을 알고 있습니다.
- 값을 임시 파일에 저장한
END { print dwt > "tempfile" }
다음 외부에서 읽습니다read dwt <tempfile; rm -f tempfile
. 그러나 기존 파일이 손상되지 않도록 여기에 표시된 것보다 더 주의를 기울인다고 해도 나는 여전히 이것을 피하는 것을 선호합니다. 다른 것이 없다면 작업이 잘못된 시간에 중단되었기 때문에 임시 파일이 남아 있는 것을 원하지 않습니다. - 또한 값을 표준 출력으로 보내지만 태그가 지정됩니다. 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
나중에 .
답변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" }'
)