3열 데이터 파일에서 "키" 발생 횟수와 관련 "값"의 합계를 인쇄합니다.

3열 데이터 파일에서 "키" 발생 횟수와 관련 "값"의 합계를 인쇄합니다.

Redis 덤프 파일을 읽기 위해 쉘을 사용하고 있습니다.

덤프 파일에는 아래와 같이 3개의 주요 열이 있습니다.

Text:tags:name    682651    520
Text:tags:age     78262     450
Value:cache       77272     672
Value:cache:name  76258     872
New:specific      77628     762
New:test          76628     8622

예상 출력:

Key     Count     Sum
Text:*  2         970
Value:* 2         1544
New:*   2         9384

문자열(키)로 시작/중간/끝날 수 있는 하위 문자열을 기반으로 열을 확인할 수 있으므로 위의 기대치를 얻고 싶습니다.

답변1

다음 awk프로그램이 이 작업을 수행합니다.

awk '{split($1,f,/:/);count[f[1]]++;sum[f[1]]+=$3}
     END{printf "Key\tCount\tSum\n"; for (k in count) {printf "%s:*\t%d\t%d\n",k,count[k],sum[k]}}' dump.txt
  • 이는 먼저 열 1 키를 :구성 요소로 분할한 다음 이를 배열에 저장합니다 f. 첫 번째 항목( f[1])은 모든 추가 처리를 위한 관련 키로 간주됩니다.
  • 발생 횟수는 count키를 f[1]배열 인덱스로 사용하여 연관 배열에 저장됩니다. 키를 찾을 때마다 1씩 증가합니다.
  • 3열의 값의 합은 유사 배열에 저장됩니다 sum.
  • 마지막으로 프로그램은 헤더 행을 인쇄한 다음 배열에서 발견된 모든 배열 인덱스를 반복하여 count배열 인덱스(= 키), 발생 횟수 및 합산된 값을 인쇄합니다.

키가 인쇄되는 순서는 awk저장된 배열의 내부 논리에 의해 정의됩니다. GNU Awk가 있는 경우 섹션의 속성을 설정하여 순회 순서를 정의할 수 있습니다 PROCINFO["sorted_in"]. BEGIN예를 들어

BEGIN{PROCINFO["sorted_in"]="@ind_str_asc"}

awk"키"를 기준으로 항목이 사전순으로 오름차순으로 인쇄 됩니다 .

답변2

첫 번째 필드 이후의 모든 내용이 다음 :으로 대체 되도록 첫 번째 필드를 수정하는 것부터 시작하세요 *.

awk -v OFS='\t' '{ sub(":.*", ":*", $1) }; 1' file

이 명령은 확장 정규 표현식의 첫 번째 항목을 리터럴 문자열로 대체하여 awk공백으로 구분된 첫 번째 필드를 수정합니다 . 데이터에 따라 탭으로 구분된 다음 데이터가 출력됩니다.:.*:*

Text:*  682651  520
Text:*  78262   450
Value:* 77272   672
Value:* 76258   872
New:*   77628   762
New:*   76628   8622

그런 다음 각 그룹의 축소된 행 수를 계산하고 세 번째 필드를 합산하면서 탭으로 구분된 첫 번째 필드로 그룹화할 수 있습니다. 한 가지 방법은 GNU를 사용하는 것입니다 datamash.

awk -v OFS='\t' '{ sub(":.*", ":*", $1) }; 1' file |
datamash groupby 1 count 1 sum 3

awk원래 입력이 정렬되지 않은 경우 데이터가 전달되거나 sort해당 datamash옵션 -s이 사용됩니다.

그러면 다음이 출력됩니다(탭으로 구분됨).

Text:*  2       970
Value:* 2       1544
New:*   2       9384

헤더를 출력하려면 먼저 다음을 호출하세요.

printf '%s\t%s\t%s\n' 'Key' 'Count' 'Sum'

완전한 것은 file몇 가지 새로운 파일을 읽고 쓰는 것입니다 output.

{
    printf '%s\t%s\t%s\n' 'Key' 'Count' 'Sum'
    awk -v OFS='\t' '{ sub(":.*", ":*", $1) }; 1' |
    datamash groupby 1 count 1 sum 3
} <file >output

답변3

$ awk -F'[:[:space:]]+' '
    { cnt[$1]++; sum[$1]+=$NF }
    END {
        print "Key", "Count", "Sum"
        for (key in cnt) {
            print key":*", cnt[key], sum[key]
        }
    }
' file | column -t
Key      Count  Sum
Value:*  2      1544
Text:*   2      970
New:*    2      9384

답변4

사용행복하다(이전 Perl_6)

~$ raku -e 'my (@k, @v); given lines.map(*.words).list {  \
            @k = .map(*.[0].split(":").[0]); @v = .map(*.[2]) };  \
            my %count1 = Bag(@k); my %agg1.=append: [Z=>] @k, @v;  \
            my %sum1; for %agg1 { %sum1.append: $_.key => [+] $_.value };  \
            for ([Z] %count1.sort, %sum1.sort) {  \
            say .[0].key ~qb[\t]~ .[0].value ~qb[\t]~ .[1].value};' file

입력 예:

Text:tags:name    682651    520
Text:tags:age     78262     450
Value:cache       77272     672
Value:cache:name  76258     872
New:specific      77628     762
New:test          76628     8622

예제 출력:

New     2   9384
Text    2   970
Value   2   1544

이 솔루션은 모든 Perl 계열 언어에 존재하는 해싱 기능을 활용하며 특별히 Raku로 작성되었습니다.

즉, lines를 읽고 각 줄은 공백으로 구분된 줄로 분할됩니다 words( map이것은 Raku가 "모든" 줄 요소 내에서 작업하도록 지시하는 것입니다). 데이터는 @k콜론 다음의 첫 번째 문자열 요소를 포함하는 배열과 세 번째 열만 포함하는 배열(0 인덱스 = 2)에 저장됩니다. 이 시점에서 배열은 다음과 같습니다.split@v

#Add this statement:
.say for @k, @v;

#Returns:
[Text Text Value Value New New]
[520 450 672 872 762 8622]

Raku에는 Bag()각 키의 발생 횟수(개수)를 제공하는 기능이 내장되어 있습니다(행 사용 my %count1 = Bag(@k);).

이로부터 및 열을 "압축"하여 함께 쌍을 이루고 해시에 넣는 %agg1집계 해시가 생성됩니다 . 물론 해시의 한 가지 속성은 각 해시가 고유하다는 것입니다. 따라서 동일한 해시와 관련된 배열 요소는 각 키를 구성하는 배열 요소에 배치됩니다 . 이 시점에서 해시는 다음과 같습니다.@k@v=>append%agg1keyvalueskeyvalue%agg1

#Add this statement:
.say for %agg1.sort;

#Returns:
New => [762 8622]
Text => [520 450]
Value => [672 872]

%agg1%sum1그런 다음 해당 해시는 다시 반복되어 개인을 합리적인 방식으로 합산하는 해시를 생성합니다. 마지막으로 데이터는 탭으로 구분되어 출력되며(따옴표로 묶은 탭은 코드에서 큰따옴표의 필요성을 줄임) 물결표를 통해 문자열 연결이 수행됩니다.valueskey~qb[\t]~\t~

https://andrewshitov.com/2020/03/16/a- Couple-of-syntax-sweets-in-raku/
https://youtu.be/wViVLytlwb8
https://raku.org

관련 정보