데이터를 추출하려는 로그 파일이 있습니다. 특정 모듈이 체크인 및 체크아웃될 때 다음과 같은 형식과 목록이 있습니다.
19:50:26 (license_manager) OUT: "certain_module" [email protected]
19:50:28 (license_manager) IN: "rarely_used_module" [email protected]
19:50:28 (license_manager) IN: "certain_module" [email protected]
19:50:28 (license_manager) IN: "different_module" [email protected]
19:50:38 (license_manager) OUT: "certain_module" [email protected]
19:50:38 (license_manager) OUT: "different_module" [email protected]
지금까지 나는 다음을 가지고 있습니다. 나는 "rarely_used_module"이 언제 확인되는지, 그리고 누가 확인하는지에 특히 관심이 있습니다.
cd /path/to/script && cat logfile.txt | grep -c "rarely_used_module"
하지만 이것은 나에게 카운트만 제공하고 다른 것은 없습니다. 나는 두 가지 이유로 이를 더 복잡하게 만들고 싶습니다. 쉘 스크립트에 대해 더 자세히 배우고 해당 스크립트에 더 많은 bash 개념을 구현하기 위해, 두 번째로 라이선스가 체크아웃된 시기와 어떤 사용자가 조회했는지 알려줄 수 있기를 원합니다. 그것.
가장 이상적인 방법은 이 라이센스가 체크아웃된 횟수를 세어 참조용으로 일종의 표로 형식화하는 것입니다. 가능합니까?
업데이트 #1
원하는 출력은 아래와 같습니다. 아래에서는 거의 사용되지 않는 모듈이 2명의 고유 사용자에 의해 4번, 개별적으로 2번 체크아웃된 이론적인 예를 제시하겠습니다.
Number of license checkouts for rarely_used_module: 4
User : [email protected] (2)
User : [email protected] (2)
기본적으로 모듈이 체크아웃된 총 횟수와 라이센스를 체크아웃한 사용자의 이름을 원합니다. "rarely_used_module"의 OUT: 행을 잡을 수 있다는 것을 알고 있지만 이를 처리하는 방법을 모르겠습니다.
답변1
업데이트된 질문의 경우:
awk '
/"rarely_used_module"/ && /OUT:/ { nc[$NF]++ ; c++ }
END {
printf "Number of license checkouts for rarely_used_module: %d\n", c
for (i in nc) printf "User: %s (%d)\n", i, nc[i]
}
' logfile.txt
다음 출력을 생성합니다.
Number of license checkouts for rarely_used_module: 4
User: [email protected] (2)
User: [email protected] (2)
요구 사항이 증가할 경우 코드를 확장하는 방법을 보여주기 위해 아래에 원래 답변을 남겨 두었습니다.
다음은 다음을 사용하여 이러한 작업을 수행하는 방법의 예입니다 awk
.
awk '
BEGIN { SUBSEP = ", " ; OFS = ": " }
{ m[$(NF-1)]++ }
{ n[$(NF-1)] = n[$(NF-1)] " " $NF }
{ nc[$(NF-1),$NF]++ }
END {
print "\n=== count modules:"
for (i in m) print i, m[i]
print "\n=== collect names using modules:"
for (i in n) print i, n[i]
print "\n=== count names using modules:"
for (i in nc) print i, nc[i]
}
' logfile.txt
설명하다:
{ m[$(NF-1)]++ }
- 입력 데이터에서 두 번째 필드(모듈)의 카운터를 증가시킵니다.{ n[$(NF-1)] = n[$(NF-1)] " " $NF }
- 각 키(모듈)의 마지막 필드(이름)를 연결합니다.{ nc[$(NF-1),$NF]++ }
- (이름, 모듈) 키 튜플의 카운터 증가
예제 데이터를 사용하면 다음과 같은 출력이 생성됩니다.
=== count modules:
"rarely_used_module": 1
"different_module": 2
"certain_module": 3
=== collect names using modules:
"rarely_used_module": [email protected]
"different_module": [email protected] [email protected]
"certain_module": [email protected] [email protected] [email protected]
=== count names using modules:
"different_module", [email protected]: 1
"different_module", [email protected]: 1
"certain_module", [email protected]: 2
"rarely_used_module", [email protected]: 1
"certain_module", [email protected]: 1
답변2
모든 줄을 변경하거나 일치시키는 것보다 더 복잡한 것이 필요할 때 Python은 범용 언어이기 때문에 사용합니다. awk
(btw, Python awk가 있습니다 ) 보다 더 장황할 수도 있지만 pawk
잘 문서화되어 있고 쉽게 확장할 수 있는 코드도 제공합니다.
다음은 작업에 적합한 Python 2 스크립트입니다.
from collections import defaultdict
FILE = 'module.txt'
# Global table of usages is
# dict [ module_name ] -> dict [ user_name ] -> count
usage = defaultdict(lambda : defaultdict(int))
# Read, parse data and add usage count where needed
with open(FILE) as f:
for line in f:
# Split using spaces and pick last 2 fields,
# strip unncessary characters
fields = line.split()
user = fields[-1].rstrip()
module_name = fields[-2].strip('"')
usage[module_name][user] += 1
# Now print pretty results
for module_name, module_usage in usage.items():
print '====> ', module_name
for user, count in module_usage.items():
print '\t', user, count
샘플에 대해 다음 데이터가 인쇄됩니다.
====> different_module
[email protected] 1
[email protected] 1
====> rarely_used_module
[email protected] 1
====> certain_module
[email protected] 2
[email protected] 1