파일에서 숫자를 파악하고 잘라서 합산하는 방법

파일에서 숫자를 파악하고 잘라서 합산하는 방법

로그 파일이 있습니다. 특정 숫자가 있는 각 행에 대해 이 행의 마지막 숫자의 합계를 계산하고 싶습니다. grep과 cut을 사용하면 문제가 없지만 숫자의 합을 계산하는 방법을 모르겠습니다. StackExchange에서 몇 가지 솔루션을 시도했지만 제 경우에는 작동하지 않았습니다.

이것이 내가 지금까지 가지고 있는 것입니다:

grep "30201" logfile.txt | cut -f6 -d "|"

30201이 제가 찾고 있는 라인입니다.

마지막 숫자 650, 1389, 945를 추가하고 싶습니다.

로그파일.txt

Jan 09 2016|09:15:17|30201|1|SL02|650
Jan 09 2016|09:15:18|43097|1|SL01|945
Jan 09 2016|09:15:19|28774|2|SB03|1389
Jan 09 2016|09:16:21|00788|1|SL02|650
Jan 09 2016|09:17:25|03361|3|SL01|945
Jan 09 2016|09:17:33|08385|1|SL02|650
Jan 09 2016|09:18:43|10234|1|SL01|945
Jan 09 2016|09:21:55|00788|1|SL02|650
Jan 09 2016|09:24:43|03361|3|SB03|1389
Jan 09 2016|09:26:01|30201|1|SB03|1389
Jan 09 2016|09:26:21|28774|2|SL02|650
Jan 09 2016|09:26:25|00788|1|SL02|650
Jan 09 2016|09:27:21|28774|2|SL02|650
Jan 09 2016|09:29:32|30201|1|SL01|945
Jan 09 2016|09:30:12|34032|1|SB03|1389
Jan 09 2016|09:30:15|08767|3|SL02|650

답변1

추가에 적합한 형식으로 paste숫자를 일련화하는 데 도움을 요청할 수 있습니다.bc

% grep "30201" logfile.txt | cut -f6 -d "|"
650
1389
945

% grep "30201" logfile.txt | cut -f6 -d "|" | paste -sd+
650+1389+945

% grep "30201" logfile.txt | cut -f6 -d "|" | paste -sd+ | bc
2984

PCRE가 있는 경우 공격적인 역방향만 사용하여 이 작업을 수행 grep할 수 있습니다 .grep

% grep -Po '\|30201\|.*\|\K\d+' logfile.txt | cut -f6 -d "|" | paste -sd+ | bc
2984

단독으로 사용 awk:

% awk -F'|' '$3 == 30201 {sum+=$NF}; END{print sum}' logfile.txt        
2984
  • -F'|'필드 구분 기호를 다음으로 설정하세요.|
  • $3 == 30201 {sum+=$NF}세 번째 필드가 다음인 경우 마지막 필드의 값을 추가합니다.30201
  • END{print sum}인쇄sumEND

답변2

grep 및 cut 명령에는 아무런 문제가 없습니다. 검색 패턴으로 "|30201|"을 사용하면 더욱 강력하게 만들 수 있습니다. 다음 문제는 출력을 처리하는 것입니다.

배시 사용:

#!/bin/bash
# get the output as a bash array and add the elements
nums=( $(grep "|30201|" logfile.txt | cut -f6 -d "|") )
total=0

for i in ${!nums[@]}
    do
    total=$(($total+${nums[i]}))
    done
echo $total

답변3

쿵쿵 솔루션.

#!/bin/bash
pa=0 ; s=0 ; 
while read a b ; do \
  if [ "$a" == "$pa" ] ; then \
    s=$(($s+$b)) ; 
   else 
    if [ "$pa" != 0 ] ; then \
      echo $pa $s ; 
    fi ; 
    pa=$a ; s=$b ; 
  fi ; 
done < <(cat j.txt | awk -F'|' '{printf("%s %s\n",$3,$6)}' | sort -n) 
echo $pa $s

이전 A 및 SUM 초기화

필드 3과 6에 대한 입력을 줄이고 숫자로 정렬

필드 3이 변경되지 않는 한 반복하고 필드 6을 SUM에 추가합니다.

필드 3이 변경되었지만 이전 A가 0이 아닌 경우 이전 A와 SUM을 출력하고 이전 A를 a로 다시 초기화한 다음 마지막으로 읽은 필드 6으로 SUM을 다시 초기화합니다.

마지막 이전 A와 SUM을 출력합니다.

입력이 주어지면 출력:

00788 1950
03361 2334
08385 650
08767 650
10234 945
28774 2689
30201 2984
34032 1389
43097 945

답변4

나는 sumcol이라고 부르는 작은 도구를 가지고 다닙니다.

#!/bin/sh
# Icarus Sparry. Free for any use.
C=${1:?"missing required column number"}
shift
awk '{s+=$'"$C"'} END { print s }' "$@"

그러면 제공한 공백으로 구분된 열이 합산됩니다. 글을 쓸 수는 있지만 (@heemayl이 그러하듯이)

awk -F'|' '$3 == 30201 {s+=$6} END{ print s}' logfile.txt

OP의 질문에 그는 다음을 사용할 수 있습니다.

grep "30201" logfile.txt | cut -f6 -d "|" | sumcol 1

또는

grep "30201" logfile.txt | tr "| " " _" | sumcol 6

관련 정보