본문 바로가기

TroubleShooting/ShellScript

텍스트 파일에서 특정 문자열들이 몇번이나 나왔는지를 알아보는 스크립트

728x90

텍스트 파일에서 특정 문자열들이 몇번이나 나왔는지를 알아보는 스크립트


텍스트 파일에서 통계를 내기 위한 목적으로 특정 문자열이 몇 번 나왔는지 알아보기 위해 여러 명령어를 조합해서 쉘 스크립트(bash 로 작성)를 만들어보았다.


2017/07/01 11:01:02.793 ERROR (Command.java:175) - MyException com.xxx.exception.MyException: [ERROR_TYPE_1]

        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:721)

        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)

        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)

        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)

        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656)

2017/07/01 11:02:32.219 ERROR (Command.java:175) - MyException

com.xxx.exception.MyException: [ERROR_TYPE_3]

        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:721)

        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)

        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)

        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)

        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656)

2017/07/01 11:03:13.123 ERROR (Command.java:175) - MyException

com.xxx.exception.MyException: [ERROR_TYPE_25]

        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:721)

        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)

        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)

        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)

        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656)

2017/07/01 11:03:22.701  WARN (Command.java:173) - MyException request : [a=123, b=567]

2017/07/01 11:04:03.123 ERROR (Command.java:175) - MyException

com.xxx.exception.MyException: [ERROR_TYPE_87]

        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:721)

        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)

        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)

        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)

        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656)

2017/07/01 11:04:03.123 ERROR (Command.java:175) - MyException com.xxx.exception.MyException: [ERROR_TYPE_1]

        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:721)

        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)

        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)

        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)

        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656)

2017/07/01 11:04:05.211  WARN (Command.java:173) - MyException request : [a=89, b=2345]

2017/07/01 11:05:28.123 ERROR (Command.java:175) - MyException

com.xxx.exception.MyException: [ERROR_TYPE_2]

        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:721)

        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)

        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)

        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)

        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656)

2017/07/01 11:04:05.211  WARN (Command.java:173) - MyException request : [a=32, b=765]

2017/07/01 11:06:28.123 ERROR (Command.java:175) - MyException

com.xxx.exception.MyException: [ERROR_TYPE_3]

        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:721)

        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)

        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)

        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)

        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656)



 위의 텍스트 내용은 자바 프로그램에서 발생한 익셉션을 저장한 로그 파일의 예이다.

 2017년 7월 1일 11 시부터 발생했는데, MyException 이라는 익셉션과 WARN, ERROR 레벨이 같이 섞여있는것을 볼 수 있다. 여기서 알고 싶은것은 로그 레벨이 ERROR 이면서 ERROR_TYPE_숫자 에 해당하는 익셉션들이 몇번이나 나타났을까이다.


 그래서 작성한 스크립트를 먼저 올려본다.

<get.sh>

: 스크립트의 내용은 아래와 같은 순서로 실행된다. 

1. 로그 파일에서 MyException 를 가진 라인들만 text.txt.grep 파일로 이동.

2. 같은 내용끼리 정렬시켜서 test.txt.sort 에 저장.

3. trap.sh 스크립트를 실행해서 "exceiption_message" 파일에 포함된 단어를 가진 라인들만 뽑아내서 test.txt.trap 파일에 저장.


#! /bin/bash


if [ "$#" -ne 2 ]; then

  echo "Usage: `basename $0` [log_file] [result_save_file]"

  exit 1;

fi


if [ ! -f $1 ]; then

  echo "`logfile $1` is not found."

  exit 2;

fi


echo "grep ..."

fgrep "com.xxx.exception.MyException" $1 > /tmp/$1.grep

#fgrep "NullPointerException" $1 >> /tmp/$1.grep


echo "sorting ..."

sort /tmp/$1.grep > /tmp/$1.sort


echo "traping ..."

./trap.sh /tmp/$1.sort > /tmp/$1.trap


echo "awk working ..."

awk -F'=' '{print $2}' /tmp/$1.trap > $2


<trap.sh>

: sort 된 파일을 입력($1) 으로 받아서 전체 line 을 돌면서(for line in $filelines) "exception_message)" 파일에서 읽은 문자열들과 비교해서문자열을 포함하고 있다면($line =~ $i) , 그 line 의 첫번째, 두번째 필드들을 뽑아서(=시간값)  "=찾는문자열"과 합친다. 말로 하니 복잡한데 밑에처럼 문자열이 만들어진다. 로그가 생성된 시간이 필요해서 시간값을 가진 필드들을 추가했다.

ex) 

2017/07/01 11:01:02.793=ERROR_TYPE_1

2017/07/01 11:04:03.123=ERROR_TYPE_1



#! /bin/bash

IFS=$'\n'

messages=`cat exception_message`

filelines=`cat $1`

for line in $filelines ; do

        for i in ${messages[*]}

        do

                if [[ $line =~ $i ]]; then

#                       echo $line

                        timestr=`echo $line | awk '{print $1" "$2}'`

                        echo $timestr'='$i

                fi

        done

done


<exception_message>

: ERROR_TYPE 들을 직접 입력한다. 통계를 낼 단어들을 입력한다.

ERROR_TYPE_1

ERROR_TYPE_2

ERROR_TYPE_3

ERROR_TYPE_4

ERROR_TYPE_5

ERROR_TYPE_25

ERROR_TYPE_87


실행 방법

./get.sh test.txt out.txt

# cat out.txt

ERROR_TYPE_1

ERROR_TYPE_1

ERROR_TYPE_2

ERROR_TYPE_25

ERROR_TYPE_2

ERROR_TYPE_3

ERROR_TYPE_3

ERROR_TYPE_87


# sort out.txt | uniq -c | sort -nr

      2 ERROR_TYPE_3

      2 ERROR_TYPE_2

      2 ERROR_TYPE_1

      1 ERROR_TYPE_87

      1 ERROR_TYPE_25