![awk 출력의 다양한 필드에 여러 변수 설정](https://linux55.com/image/184653/awk%20%EC%B6%9C%EB%A0%A5%EC%9D%98%20%EB%8B%A4%EC%96%91%ED%95%9C%20%ED%95%84%EB%93%9C%EC%97%90%20%EC%97%AC%EB%9F%AC%20%EB%B3%80%EC%88%98%20%EC%84%A4%EC%A0%95.png)
나는 상당히 줄일 수 있다고 생각하는 변수 초기화를 많이 가지고 있습니다. 구문 분석되는 파일은 다음과 같습니다.
-------------------- ACL Stats Per Interface ----------------------
Entries Packets Dropped
Recent Total PerMax Recent Total PerMax
Slot 0 /Port 0
Trusted 1 196 1311578 386 0 0 0
Untrusted 3 20 217217953 852794 0 0 0
...스크립트의 코드 조각은 다음과 같습니다.
expect_results="stats.txt"
acl_stats_per_interface_trusted_entries_s0_p0=`grep -A 2 "Slot 0 /Port 0" $expect_results | grep "Trusted" | awk '{print $2}' `
acl_stats_per_interface_trusted_recent_packets_s0_p0=`grep -A 2 "Slot 0 /Port 0" $expect_results | grep "Trusted" | awk '{print $3}' `
acl_stats_per_interface_trusted_total_packets_s0_p0=`grep -A 2 "Slot 0 /Port 0" $expect_results | grep "Trusted" | awk '{print $4}' `
acl_stats_per_interface_trusted_permax_packets_s0_p0=`grep -A 2 "Slot 0 /Port 0" $expect_results | grep "Trusted" | awk '{print $5}' `
acl_stats_per_interface_trusted_dropped_recent_s0_p0=`grep -A 2 "Slot 0 /Port 0" $expect_results | grep "Trusted" | awk '{print $6}' `
acl_stats_per_interface_trusted_dropped_total_s0_p0=`grep -A 2 "Slot 0 /Port 0" $expect_results | grep "Trusted" | awk '{print $7}' `
acl_stats_per_interface_trusted_dropped_permax_s0_p0=`grep -A 2 "Slot 0 /Port 0" $expect_results | grep "Trusted" | awk '{print $8}' `
grep
동일한 파일을 7번 ping하고 한 번만 grep하여 이러한 변수를 각 개별 awk
출력 으로 설정하는 방법이 있습니까 ?
답변1
FWIW 저는 awk를 사용하여 입력 파일에서 텍스트와 값을 추출하고 그 출력을 수동으로 셸 변수 등을 만들지 않고도 .prom 파일로 인쇄합니다.
$ cat tst.awk
$1 ~ /^-+$/ {
# -------------------- ACL Stats Per Interface ----------------------
gsub(/^[[:space:]]*-+[[:space:]]+|[[:space:]]+-+[[:space:]]*$/,"")
fileHdr = $0
next
}
/^[[:space:]]/ {
if (NF == 3) {
# Entries Packets Dropped
colName[1] = $1
for (i=2; i<=NF; i++) {
colHdr[i] = $i
}
}
else {
# Recent Total PerMax Recent Total PerMax
for (i=1; i<=3; i++) {
colName[i+1] = $i "_" colHdr[2]
}
for (; i<=NF; i++) {
colName[i+1] = $i "_" colHdr[3]
}
}
next
}
/^Slot/ {
# Slot 0 /Port 0
slot = $2
port = $NF
next
}
/^[[:alpha:]]/ {
# Trusted 1 196 1311578 386 0 0 0
# Untrusted 3 20 217217953 852794 0 0 0
rowName = $1
for (i=2; i<=NF; i++) {
out = tolower(fileHdr "_" rowName "_" colName[i-1] "_s" slot "_p" port) "=" $i
gsub(/[[:space:]]+/,"_",out)
print out
}
}
$ awk -f tst.awk file
acl_stats_per_interface_trusted_entries_s0_p0=1
acl_stats_per_interface_trusted_recent_packets_s0_p0=196
acl_stats_per_interface_trusted_total_packets_s0_p0=1311578
acl_stats_per_interface_trusted_permax_packets_s0_p0=386
acl_stats_per_interface_trusted_recent_dropped_s0_p0=0
acl_stats_per_interface_trusted_total_dropped_s0_p0=0
acl_stats_per_interface_trusted_permax_dropped_s0_p0=0
acl_stats_per_interface_untrusted_entries_s0_p0=3
acl_stats_per_interface_untrusted_recent_packets_s0_p0=20
acl_stats_per_interface_untrusted_total_packets_s0_p0=217217953
acl_stats_per_interface_untrusted_permax_packets_s0_p0=852794
acl_stats_per_interface_untrusted_recent_dropped_s0_p0=0
acl_stats_per_interface_untrusted_total_dropped_s0_p0=0
acl_stats_per_interface_untrusted_permax_dropped_s0_p0=0
게시한 입력 파일과 동일한 형식으로 다른 파일을 생성하는 도구가 있는 경우 위의 awk 스크립트는 특별한 쉘 스크립트를 만들 필요 없이 있는 그대로 작동해야 합니다. 다른 형식의 입력 파일에 대해 동일한 접근 방식을 사용하도록 스크립트를 조정할 수 있습니다.
답변2
read
내장 함수를 사용하여 행을 읽고 변수에 여러 값을 할당할 수 있습니다 .
오류 처리 및 더 짧은 변수 이름의 예:
if read dummy var1 var2 var3 var4 var5 var6 var7 extra
then
echo OK
else
echo EOF
fi < <(grep -A 2 "Slot 0 /Port 0" $expect_results | grep "Trusted")
if [ -n "$extra" ]
then
echo too many values
fi
if [ -z "$var7" ]
then
echo not enough values
fi
echo vars: $var1 $var2 $var3 $var4 $var5 $var6 $var7
이하, 오류 처리 없이
read dummy var1 var2 var3 var4 var5 var6 var7 extra < <(grep -A 2 "Slot 0 /Port 0" $expect_results | grep "Trusted")
echo vars: $var1 $var2 $var3 $var4 $var5 $var6 $var7
코드에서는 입력이 공백, 특수 문자, 따옴표 없이 공백으로 구분된 간단한 값을 포함하는 한 줄로 구성될 것으로 예상합니다.
read
EOF 또는 잘못된 값 수에 대한 오류 처리에 대해 알아보려면 여기에 내장된 문서를 읽어보세요.https://www.gnu.org/software/bash/manual/html_node/Bash-Builtins.html
EOF에 대한 특정 오류 처리는 불필요한 것 같습니다. 이 경우(내 시스템에서는) 모든 변수가 비어 있지만 내장 문서에서 이 동작에 대한 사양을 찾을 수 없습니다 read
. EOF는 입력에서 일치하는 행을 찾을 수 없을 때 발생합니다.
답변3
나는 grep
너무 많은 변수를 인스턴스화하는 대신 명령문의 출력을 배열로 읽고 요소에 개별적으로 액세스하기로 결정했습니다.
acl_stats_trusted=( $(grep "Trusted" "$expect_results") )
echo "${acl_stats_trusted[1]}" # Outputs 1
echo "${acl_stats_trusted[3]}" # Outputs 1311578
이는 모든 사용자에게 더 간결하고 명확합니다.