awk 출력의 다양한 필드에 여러 변수 설정

awk 출력의 다양한 필드에 여러 변수 설정

나는 상당히 줄일 수 있다고 생각하는 변수 초기화를 많이 가지고 있습니다. 구문 분석되는 파일은 다음과 같습니다.

                   -------------------- 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             

코드에서는 입력이 공백, 특수 문자, 따옴표 없이 공백으로 구분된 간단한 값을 포함하는 한 줄로 구성될 것으로 예상합니다.

readEOF 또는 잘못된 값 수에 대한 오류 처리에 대해 알아보려면 여기에 내장된 문서를 읽어보세요.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

이는 모든 사용자에게 더 간결하고 명확합니다.

관련 정보