2013-05-03 5 views
3

나는 Bash 초보자에게 약간의 지식이 있으므로 여기에 나와 함께하시기 바랍니다.열 1의 결과를 합친 다음 열 1의 각 항목에 대한 합계를 나열하려면 sum 열 2를 입력하십시오.

 
Jim 109 
Bob 94 
John 92 
Sean 91 
Mark 85 
Richard 84 
Jim 79 
Bob 70 
John 67 
Sean 62 
Mark 59 
Richard 58 
Jim 57 
Bob 55 
John 49 
Sean 48 
Mark 46 
. 
. 
. 

여기 내 목표는 얻는 것입니다 :

나는 (내가 통제 할 수 없다)이 보이는 특정 리소스에 액세스 횟수와 각 사용자를 나열하는 다른 소프트웨어에 의해 버려진 텍스트 파일이 이런 식으로 출력하십시오.

 
Jim [Total for Jim] 
Bob [Total for Bob] 
John [Total for John] 

등등.

소프트웨어에서 쿼리를 실행할 때마다 이름이 바뀌므로 각 이름의 정적 검색과 wc를 통한 파이프 연결은 도움이되지 않습니다.

답변

6

awk : 파이프 다음 awk 스크립트 프로그램의 출력을위한 작업 같은 소리 :

your_program | awk '{a[$1]+=$2}END{for(name in a)print name " " a[name]}' 

출력 :

Sean 201 
Bob 219 
Jim 245 
Mark 190 
Richard 142 
John 208 

awk 스크립트 자체가 더 나은 설명 될 수있다 이 형식 :

# executed on each line 
{ 
    # 'a' is an array. It will be initialized 
    # as an empty array by awk on it's first usage 
    # '$1' contains the first column - the name 
    # '$2' contains the second column - the amount 
    # 
    # on every line the total score of 'name' 
    # will be incremented by 'amount' 
    a[$1]+=$2 
} 
# executed at the end of input 
END{ 
    # print every name and its score 
    for(name in a)print name " " a[name] 
} 

점수로 정렬 된 결과를 얻으려면 sort -r -k2에 다른 파이프를 추가 할 수 있습니다.

your_program | awk '{a[$1]+=$2}END{for(n in a)print n" "a[n]}' | sort -r -k2 

출력 :

Jim 245 
Bob 219 
John 208 
Sean 201 
Mark 190 
Richard 142 
+0

그건 마치 챔피언처럼 일했습니다. 고맙습니다! 나는 awoo '{print $ 2}'에 출력을 파이핑하여 변수로 읽어 들인 다음 변수를 합산하고 결과를 나열하려고 시도했습니다. 고마워요! –

+2

당신은 오신 것을 환영합니다. 조금 더 자세한 설명을 추가했습니다 – hek2mgl

+0

시간, 인내, 설명 및 도움을 주셔서 다시 한번 감사드립니다. 나는 언젠가는 호의를 돌려 줄 수 있기를 바랍니다. 이것은 나의 하루를 보냈다.나는 awk 사용에있어서 잘못된 접근으로 인해 좌절감을 느꼈다. 그리고 나서 사건을 합산하려고 노력하는 중첩 된 루프에 대해 불필요한 것으로 보이는 것을 사용하여 휠을 다시 발명하려고 시도하여 문제를 더욱 악화시켰다. 내가 포기하기 전에 꽤 많은 시간 낭비했다. 정말 감사합니다. 말로는 내가 얼마나 감사하고 있는지 설명 할 수 없다. –

4

순수 배시 : 역순 번째 열에 의해 -r -k2 소트

declare -A result     # an associative array 

while read name value; do 
    ((result[$name]+=value)) 
done < "$infile" 

for name in ${!result[*]}; do 
    printf "%-10s%10d\n" $name ${result[$name]} 
done 

상기 제 '완료'경우, 입력 파일로부터 리디렉션 없다 이 스크립트는 파이프와 함께 사용할 수 있습니다.

your_program | ./script.sh 

출력을

your_program | ./script.sh | sort 

출력 정렬 :

Bob    219 
Richard   142 
Jim    245 
Mark    190 
John    208 
Sean    201 
+2

bash 솔루션을 보는 +1 : – abasu

+0

@fgm. bash 솔루션에 감사드립니다. 그것은 내가 아직 초보자 인 것처럼 더 많은 배쉬를 배울 수있을 것입니다. 고마워 여러분, 정말이 모든 도움을 주셔서 감사합니다. –

1

GNUdatamash :

datamash -W -s -g1 sum 2 < input.txt 

출력 :

Bob 219 
Jim 245 
John 208 
Mark 190 
Richard 142 
Sean 201 
+0

나는 datamash에 대해 몰랐습니다. 감사. –

관련 문제