파일 내용을 가져오는 쉘 스크립트

파일 내용을 가져오는 쉘 스크립트

"data_logs"라는 디렉터리에 매분마다 로그 파일을 생성합니다.

로그 파일 이름:

abc.log.2019041607
abc.log.2019041608..

로그 파일의 내용은 다음과 같습니다

R_MT|D:1234|ID:413|S:1
R_MT|D:1234|ID:413|S:1
R_MT|D:1234|ID:413|S:1
R_MT|D:1234|ID:413|S:1
R_MT|D:1234|ID:413|S:1
R_MT|D:1234|ID:413|S:1
R_MT|D:1234|ID:413|S:1
R_MT|D:1234|ID:413|S:1
R_MT|D:1234|ID:413|S:1
R_MT|D:1234|ID:413|S:1

R_MT|D:1234|ID:413|S:0
R_MT|D:1234|ID:413|S:0
R_MT|D:1234|ID:413|S:0
R_MT|D:1234|ID:413|S:0 
R_MT|D:1234|ID:413|S:0

k_MT|D:1234|ID:414|S:1
k_MT|D:1234|ID:414|S:1
k_MT|D:1235|ID:413|S:1
k_MT|D:1235|ID:413|S:1

나는 실행될 때 지난 5분 동안 생성된 파일(마지막 5개 파일, 매분 1개 파일 생성)을 찾고 각 파일을 하나씩 열고 처리하는 쉘 스크립트를 작성하고 있습니다. 즉, 출력을 생성합니다. R_MT|D:1234|ID:413이 조합에 대해 'Committed' 열에 저장된 's'의 총 개수 0과 Uncommitted 열에 저장된 's'=1을 포함하는 txt 파일

내 output.txt는 다음과 같아야 합니다.

Type, Number,ID,submitted,notsubmitted
R_MT,D:1234,ID:413,5,10
R_MT,D:1234,ID:414,0,2
R_MT,D:1235,ID:413,0,2

나는 이것을 사용하여 커밋된 값과 커밋되지 않은 값을 얻습니다.

zcat abc.log.2019041607.gz |grep "R_MT"|awk -F"|" '{print $2","$3","$4}'|sort|uniq -c
      5 D:1234,ID:413,S:0
     10 D:1234,ID:413,S:1
      2 D:1234,ID:414,S:1
      2 D:1235,ID:413,S:1

위 명령을 사용하여 개수를 얻었지만 출력 파일의 "커밋됨" 및 "커밋되지 않은" 필드에 쓸 수 있도록 변수에 할당하는 방법을 모르고 지난 5분 동안의 문서요?

도와주세요, 정말 감사합니다!

답변1

input.log가 입력일 때 gawk와 함께 작동하는 이것이 있지만 여전히 awk로 알아내려고 노력하고 있습니다.

cat input.log |
 gawk -F"|" \
    #print the header
 'BEGIN{print"Type, Number,ID,submitted,notsubmitted"}
    #only work on non empty lines
 NF>0{ 
     #create an ID from the first three fields
    n=$1","$2","$3; 
        #everytime the ID pops up, increment subindex 1 or 2 depending on the value of field 4
        if($4=="S:1"){
            array[n][2]++}
        else{
            array[n][1]++}
}
     #print the final array
END{for(i in array){
       #if the value has never been seen declare it to be zero
        if(array[i][1]){
            m=array[i][1]}
        else {
            m=0}
        if(array[i][2]){
            n=array[i][2]}
        else {
            n=0}
    print i","m","n}
}'

답변2

지난 5분 이내에 수정된 로그 파일을 찾으려면 find예를 들어 .

find data_logs/ -type f -name 'abc.log.*' -mmin -6

다음보다 적게 수정된 로그 파일을 찾습니다.6몇 분 전만 해도 대부분의 경우 이 정도면 충분했습니다. 정확한 파일 수정 시간이 필요한 경우 다음을 사용하십시오.

find data_logs/ -type f -name 'abc.log.*' \( -mmin -5 -o -mmin 5 \)

5분 전 또는 정확히 5분 전에 수정된 파일은 찾지 않습니다.

에서 man find:

-mmin n
    File's data was last modified n minutes ago.

그리고:

숫자 매개변수는 다음과 같이 지정할 수 있습니다.

 +n     for greater than n,
 -n     for less than n,
  n     for exactly n.

답변3

교차 게시 문제https://stackoverflow.com/q/57377173/3220113보류되었습니다. 여기에 허용된 답변을 복사하겠습니다. 다른 질문은 삭제할 수 있습니다.

파일의 경우: 먼저 awk를 사용하여 스트림을 쉽게 처리할 수 있도록 만듭니다(약간 더 나은 성능을 위해 모두 awk에서 수행할 수 있음).

sed -nr 's/\|/,/g;s/(^R_MT,.*),S:([^ ]) *$/\1 \2/p' <(zcat abc.log.2019041607.gz)

결과(추가 테스트 라인 추가 후)

R_MT,D:1234,ID:413 1
R_MT,D:1234,ID:413 1
R_MT,D:1234,ID:413 1
R_MT,D:1234,ID:413 1
R_MT,D:1234,ID:413 1
R_MT,D:1234,ID:413 1
R_MT,D:1234,ID:413 1
R_MT,D:1234,ID:413 1
R_MT,D:1234,ID:413 1
R_MT,D:1234,ID:413 1
R_MT,D:1234,ID:413 0
R_MT,D:1234,ID:413 0
R_MT,D:1234,ID:413 0
R_MT,D:1234,ID:413 0
R_MT,D:1234,ID:413 0
R_MT,D:1234,ID:414 1
R_MT,D:1234,ID:414 1
R_MT,D:1235,ID:413 1
R_MT,D:1235,ID:413 1

이제 배열 a를 필드 이름으로 사용하여 awk에서 계산합니다.

sed -nr 's/\|/,/g;s/(^R_MT,.*),S:([^ ]) *$/\1 \2/p' <(zcat abc.log.2019041607.gz) |
   awk '{a[$1]; if ($2>0) notsub[$1]++; else submit[$1]++;}
        END {for (i in a) print i "," submit[i]+0 "," notsub[i]+0;}
       '

5개 파일의 경우 먼저 원하는 결과를 결정하세요. 각 파일마다 다른 출력 파일을 갖습니다. 다음과 같은 루프를 사용하십시오.

while IFS= read -r filename; do
   ... <( zcat "${filename}") ...
done < <(find datalogs -type f -name "abc*" -mmin -5)

5개 파일의 결과가 단일 합계에 추가됩니다.

... <( find datalogs -type f -name "abc*" -mmin -5 -exec zcat {} \;) ...

답변4

원하는 시간을 기준으로 파일을 쉽게 찾을 수 있습니다. 그러나 결과를 얻으려면 awk다음과 같이 사용할 수 있습니다.

  awk -F\| '!/^\s*$/{if($4=="S:0"){Arr0[$1","$2","$3]+=1} else {Arr1[$1","$2","$3]+=1}}END{for(i in Arr1){print i,",",Arr0[i],",",Arr1[i]}}'

설명하다:

  1. -F\|: |필드 구분 기호로 정의됨

  2. !/^\s*$/: 빈 줄 건너뛰기

  3. if(Clause){Statement}else{statement}: 분명한

  4. END{...}: 이 블록은 연산자가 EOF에 도달하면 실행됩니다.

관련 정보