grep의 마지막 몇 줄의 출력을 온라인에 넣는 방법은 무엇입니까?

grep의 마지막 몇 줄의 출력을 온라인에 넣는 방법은 무엇입니까?

다음 파일이 있다고 가정해 보겠습니다.

 Thu May  8 15:32:07 2014
        User-Name = "Mark"
        Framed-IP-Address = 0.0.0.0
        Acct-Status-Type = Interim-Update
        Acct-Input-Octets = 95684
        Acct-Output-Octets = 23564

    Thu May  8 15:32:07 2014
        User-Name = "Mike"
        Framed-IP-Address = 0.0.0.0
        Acct-Status-Type = Interim-Update
        Acct-Input-Octets = 95684
        Acct-Output-Octets = 23564
    Thu May  8 15:32:07 2014
        User-Name = "Mike"
        Framed-IP-Address = 0.0.0.0
        Acct-Status-Type = Interim-Update
        Acct-Input-Octets = 95684
        Acct-Output-Octets = 23564

    Thu May  8 15:32:07 2014
        User-Name = "Mark"
        Framed-IP-Address = 0.0.0.0
        Acct-Status-Type = Interim-Update
        Acct-Input-Octets = 95684
        Acct-Output-Octets = 23564

grepwith 옵션을 사용하여 사용자와 관련된 정보를 얻었습니다 -A.

grep -A4 "Mark" test
        User-Name = "Mark"
        Framed-IP-Address = 0.0.0.0
        Acct-Status-Type = Interim-Update
        Acct-Input-Octets = 95684
        Acct-Output-Octets = 23564
--
        User-Name = "Mark"
        Framed-IP-Address = 0.0.0.0
        Acct-Status-Type = Interim-Update
        Acct-Input-Octets = 95684
        Acct-Output-Octets = 23564

하지만 내가 원하는 결과는 다음과 같습니다.

User-Name = "Mark" 
            Acct-Input-Octets = 95684 95684
            Acct-Output-Octets = 23564 23564

Framed-IP-Address = 0.0.0.0우리가 알아차린 대로 "Mark" 다음의 처음 두 행을 제거 하고 Acct-Status-Type = Interim-Update동일한 필드의 모든 값을 동일한 행에 배치하고 싶습니까 ?

~처럼워릭제안, 내 질문의 첫 번째 부분은 쉽게 대답할 수 있습니다.

grep -A4 "Mark" test| grep -v Framed-IP-Address | grep -v Acct-Status-Type

이는 하나의 예이며 파일에는 사용자 이름="Mark"가 포함된 많은 섹션이 포함될 수 있으며 원하는 출력은 다음과 유사합니다.

User-Name = "Mark" 
                Acct-Input-Octets = val1 val2 val3 val4 .......
                Acct-Output-Octets = val1 val2 val3 val4 ........

답변1

search.awk

BEGIN {
    FS = "="
    cur_username = ""
}

$1 ~ /User-Name/ {
    cur_username = $2
    gsub(/^[ \t]+/, "", cur_username)
    gsub(/[ \t]+$/, "", cur_username)
}

$1 !~ /User-Name/ {
    if ((NF != 2) || (cur_username != searched_user))
        next

    key = $1
    gsub(/^[ \t]+/, "", key)
    gsub(/[ \t]+$/, "", key)

    value = $2
    gsub(/^[ \t]+/, "", value)
        gsub(/[ \t]+$/, "", value)

    values[key] = values[key] " " value
}

END {
    printf("User-Name = %s\n", searched_user)
    for(key in values) {
        printf("\t%s =%s\n", key, values[key])
    }
}

테스트 실행:

$ awk -f search.awk -v 'searched_user="Mark"' input 
User-Name = "Mark"
    Acct-Status-Type = Interim-Update Interim-Update
    Acct-Input-Octets = 95684 95684
    Framed-IP-Address = 0.0.0.0 0.0.0.0
    Acct-Output-Octets = 23564 23564

보너스 - group.awk모든 레코드를 그룹화하는 경우(안타깝습니다.노크아니요asorti):

BEGIN {
    FS = "="
    cur_username = ""
}

$1 ~ /User-Name/ {
    cur_username = $2
    gsub(/^[ \t]+/, "", cur_username)
    gsub(/[ \t]+$/, "", cur_username)
}

$1 !~ /User-Name/ {
    if (NF != 2)
        next

    key = $1
    gsub(/^[ \t]+/, "", key)
    gsub(/[ \t]+$/, "", key)

    value = $2
    gsub(/^[ \t]+/, "", value)
        gsub(/[ \t]+$/, "", value)

    users[cur_username,key] = users[cur_username,key] " " value
}

END {
    n = asorti(users, sorted)
    prev_username = ""
    for (i=1; i<=n; i++) {
        username_key = sorted[i]
        split(username_key, a, SUBSEP)
        username = a[1]
        key = a[2]
        value = users[sorted[i]]
        if (username != prev_username) {
            printf("User-Name = %s\n", username)
            prev_username = username
        }
        printf("\t%s =%s\n", key, value)
    }
}

테스트 실행:

$ gawk -f group.awk input 
User-Name = "Mark"
    Acct-Input-Octets = 95684 95684
    ...
User-Name = "Mike"
    Acct-Input-Octets = 95684 95684
    ...

답변2

당신은 다음과 같은 것을 할 수 있습니다

awk -vRS= -F'\n' '$2 ~ /Mark/ {
  vals["User-Name"] = "Mark"
  for (i=5;i<=NF;i++) {
    split($i,a," = ");
    vals[a[1]]=sprintf("%s %s", vals[a[1]], a[2]);
  }
}     
END{for (i in vals) print i,"=",vals[i];}' test

test귀하의 파일에 대해 그것은 제공합니다

User-Name = Mark
        Acct-Input-Octets =  95684 95684
        Acct-Output-Octets =  23564 23564

답변3

  1. 이 사용자에 대한 데이터를 수집하려면 필수 단락을 필터링하세요.
  2. 필수 키( Acct-Input-OctetsAcct-Output-Octets)가 포함된 행을 필터링합니다. 간격이 일관되지 않으면 이 단계에서 간격을 표준화해야 할 수도 있습니다.
  3. 키별로 항목을 정렬합니다(값의 순서에 관심이 없다면 안정적인 정렬을 사용하세요).
  4. 동일한 키의 순서를 축소합니다.
awk -v RS= '/User-Name = "Mark"/' |
grep -E 'Acct-(Input|Output)-Octets *=' |
sort -k1,1 -s |
awk '
  BEGIN {printf "User-Name = \"Mark\""}
  $1 == key { printf " %s", $3; }
  $1 != key { key = $1; printf "\n%s", $0; }
  END { print "" }'

관련 정보