awk 배열을 이전 줄의 배열과 비교

awk 배열을 이전 줄의 배열과 비교

도와주시면 감사하겠습니다. 어떤 경우에는 크기가 테라바이트를 초과하는 데이터 파일에서 정보를 추출하고 있습니다.

  • 각 줄의 변수는 공백으로 구분됩니다.
  • 각 줄의 변수 수는 각 파일마다 고정되어 있습니다.
  • 오른쪽 세 열은 항상 자연수
  • 줄은 항상 배열로 시작됩니다.
  • 배열에는 항상 파일당 고정된 양의 요소가 포함됩니다.
  • 배열은 1~5개의 요소를 포함할 수 있습니다.
  • 소스 데이터 파일이 올바르게 정렬되었습니다.

아래 샘플은 병렬을 사용할 때 세 요소 배열을 파일이나 청크의 다른 모든 배열과 비교합니다. 배열이 일치하면 오른쪽에서 두 번째 열이 추가되고 행이 병합됩니다. 가장 오른쪽 열과 -2 열이 플러시됩니다.

g@grml # zcat googlebooks-eng-us-all-3gram-20120701-zz.gz | head
Z'Z . _END_     1840    1       1
Z'Z . _END_     1847    1       1
Z'Z . _END_     1850    1       1
Z'Z . _END_     1855    1       1
Z'Z . _END_     1856    1       1
Z'Z . _END_     1857    1       1
Z'Z . _END_     1860    1       1
Z'Z . _END_     1863    1       1
Z'Z . _END_     1865    1       1
Z'Z . _END_     1869    1       1



g@grml # zcat googlebooks-eng-us-all-3gram-20120701-zz.gz | parallel -k -q --pipe awk '{a[$1" "$2" "$3] +=$(NF-1)} END{for (i in a) print i, a[i]}' | head 
Zz_NOUN _NOUN_ , 98
zz _._ _PRT_ 120
ZZ or_CONJ _NOUN_ 122
ZZ_NOUN _DET_ _VERB_ 59
zz_DET _NOUN_ . 86
ZZ is_VERB reached 42
ZZ_NUM ^ ^ 65
ZZ _NOUN_ _VERB_ 3163
ZZ ,_. " 52
ZZ / _NUM_ 275

예제에서는 요소가 3개인 배열을 설명하지만 저는 1~5개의 요소가 포함된 배열을 사용하여 작업하고 있습니다.

awk '{a[$1] +=$(NF-1)} END{for (i in a) print i, a[i]}'
awk '{a[$1" "$2] +=$(NF-1)} END{for (i in a) print i, a[i]}'
awk '{a[$1" "$2" "$3] +=$(NF-1)} END{for (i in a) print i, a[i]}'
awk '{a[$1" "$2" "$3" "$4] +=$(NF-1)} END{for (i in a) print i, a[i]}'
awk '{a[$1" "$2" "$3" "$3" "$5] +=$(NF-1)} END{for (i in a) print i, a[i]}'

awk가 모든 배열을 파일이나 청크의 모든 배열과 일치시키려고 시도하는 대신 현재 배열을 이전 줄의 이전 배열과 비교하도록 awk에 어떻게 지시합니까?

감사합니다

예제 소스 파일.

wget --show-progress -cq http://storage.googleapis.com/books/ngrams/books/googlebooks-eng-us-all-3gram-20120701-zz.gz -O - | zcat

답변1

댓글에 URL로 제공되는 입력 데이터는 탭으로 구분됩니다. 이는 탭으로 구분된 첫 번째 필드를 일종의 "키"로 구문 분석하여 다른 줄과 비교할 수 있음을 의미합니다. 우리는하다~ 아니다첫 번째 필드 내에서 공백으로 구분된 단어에 주의해야 하지만 첫 번째 필드 전체를 단일 엔터티로 처리할 수 있습니다.

BEGIN { OFS = FS = "\t" }

{
    count = $(NF - 1)
    key = $1
}

key != previous {
    if (previous != "")
        print previous, sum

    sum = 0
}

{
    sum += count
    previous = key
}

END {
    if (previous != "")
        print previous, sum
}

awk프로그램은 "count" 필드(마지막 필드에서 두 번째)를 구문 분석한 count다음 첫 번째 필드를 "키"로 사용하여 나중에 이전 줄의 키와 비교합니다. 이는 BEGIN블록(입력 및 출력 구분 기호만 설정) 다음의 첫 번째 블록입니다 .

키가 이전 줄의 키와 다르다면 이는 이제 다른 단어 집합을 보고 있다는 의미입니다. 이전 라인의 키와 합을 출력하고 합을 재설정합니다.

모든 줄에 대해 이 줄의 개수만큼 합계를 늘리고 업데이트합니다 previous(이제 이 줄은 끝났으므로 이 줄은 key다음 줄이 됩니다 previous).

마지막에는 데이터의 마지막 줄에 대한 정보를 출력합니다.

를 사용하여 이를 실행합니다 awk -f script.awk inputfile.

"한 줄짜리"로:

awk -F '\t' 'BEGIN{OFS=FS} {c=$(NF-1);k=$1} k!=p {if(p!="")print p,s;s=0} {s+=c;p=k} END {if(p!="") print p,s}' file

관련 정보