"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]}}'
설명하다:
-F\|:
|
필드 구분 기호로 정의됨!/^\s*$/: 빈 줄 건너뛰기
if(Clause){Statement}else{statement}
: 분명한END{...}
: 이 블록은 연산자가 EOF에 도달하면 실행됩니다.