본문 바로가기

프로그래밍

[Linux] awk 명령어 텍스트 처리 활용하기

awk 명령어는 기능을 개발한 사람들의 이니셜을 조합하여 (Aho + Weinberger + Kernighan) 명령어 이름이 awk로 사용됩니다.

 

awk는 데이터를 조작 및 연산하고 생성하는 데 사용되는 스크립팅 언어입니다. awk 명령 프로그래밍 언어는 컴파일 할 필요가 없으며 변수, 숫자 함수, 문자열 함수 및 논리 연산자를 사용할 수 있습니다.

awk는 프로그래머가 문서의 각 줄에서 검색 할 텍스트 패턴과 문서에서 일치하는 항목을 찾을 때 수행 할 작업을 정의하는 문장 형식으로 작지만 효과적인 프로그램을 작성할 수있는 유틸리티입니다. awk는 주로 패턴 스캐닝 및 처리에 사용됩니다. 하나 이상의 파일을 검색하여 지정된 패턴과 일치하는 행이 있는지 확인한 후 연관된 조치를 수행합니다.

 

1. AWK 작업 :
 (a) 파일을 한 줄씩 스캔합니다.
 (b) 각 입력 줄을 필드로 나눕니다.
 (c) 입력 줄 / 필드를 패턴과 비교합니다.
 (d) 일치하는 줄에서 작업을 수행합니다.

 

awk 스크립트를 사용하려면 다음과 같이 작은 따옴표로 묶은 중괄호를 사용해야 합니다.

사용법

 awk [option] 'pattern {action}' [input-file]

 

2. awk 옵션

 -F fs                    파일 구분 기호를 지정합니다.
 -f file                   awk 스크립트가 포함 된 파일 을 지정합니다.
 -v var = value       변수를 선언합니다.

 

3. awk 사용 예제

$ cat testfile 

출력
This is a apple
linux is best os
I am the best programmer.
My hobby is riding a bicycle.
Coding is so much fun.

 

각 줄의 첫 단어를 출력

$ awk '{print $1}' testfile

출력
This
linux
I
My
Coding

 

-F 옵션을 사용하여 ':' 구분자 기준으로 첫 번째 필드 출력

$ awk -F : '{print $ 1}' /etc/passwd

출력
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
uucp
operator
games
gopher
ftp
nobody
dbus
vcsa
abrt
haldaemon
ntp
saslauth
postfix
sshd
tcpdump
cobin66

 

여러 명령 실행은 ';' 으로 구분합니다.

첫 번째 명령은 $3 필드 값을 변경하고 두 번째 명령은 전체 줄을 출력합니다.

$ echo "simple is best" | awk '{$3 = "good"; print $0}'

출력
simple is good

 

파일에서 스크립트 읽기

awk 스크립트를 파일에 입력하고 -f 옵션을 사용하여 해당 파일을 지정할 수 있습니다.

$ cat scriptfile 

출력
{print $1 " &&&& " $2 " " $3}
$ awk -f scriptfile testfile 

출력
This &&&& is a
linux &&&& is best
I &&&& am the
My &&&& hobby is
Coding &&&& is so

 

일치하는 패턴의 전체 행 출력

/패턴/ 형태로 입력합니다.

$ awk '/Coding/ {print $0}' testfile 

출력
Coding is so much fun.

 

패턴별로 열 인쇄

패턴 일치가 성공하면 AWK는 기본적으로 전체 레코드를 인쇄합니다. 그러나 특정 필드 만 인쇄하도록 AWK에 지시 할 수 있습니다. 예를 들어, 다음 예는 패턴 일치가 성공하면 세 번째 및 네 번째 필드를 인쇄합니다.

$ awk '/a/ {print $3 "\t" $4}' testfile 

출력
a	apple
the	best
is	riding

 

일치 패턴 계산 및 인쇄

패턴 일치에 성공한 줄 수를 세고 인쇄 할 수있는 예를 살펴 보겠습니다.

$ awk '/best/{++cnt} END {print "Count = ", cnt}' testfile

출력
Count =  2

 

20자를 초과하는 줄 인쇄

20자를 초과하는 줄만 인쇄하겠습니다.

$ awk 'length($0) > 20' testfile

출력
I am the best programmer.
My hobby is riding a bicycle.
Coding is so much fun.

 

ARGV

명령 행 인수를 저장하는 배열입니다. 배열의 유효한 인덱스 범위는 0에서 ARGC-1입니다.

$ awk 'BEGIN { 
   for (i = 0; i < ARGC - 1; ++i) {
      printf "ARGV[%d] = %s\n", i, ARGV[i]
   }
}' one two three four

출력
ARGV[0] = awk
ARGV[1] = one
ARGV[2] = two
ARGV[3] = three

 

파일 이름

현재 파일 이름을 나타냅니다.

$ awk 'END {print FILENAME}' testfile 

출력
testfile

 

NF

현재 레코드의 필드 수를 나타냅니다. 예를 들어 다음 예제는 필드가 두 개 이상 포함 된 행만 인쇄합니다.

$ cat testfile | awk '{print NF}'

출력
4
4
5
6
5
$ cat testfile | awk 'NF > 4'

출력
I am the best programmer.
My hobby is riding a bicycle.
Coding is so much fun.

 

awk script 파일로 문자열 가공하기

$ vi testlog2

2020-07-13 09:21:31 KST [ISP.0090.0003C] BIS_ITS_Formation_BY100 [ BIS TO ITS ] ###################################################
2020-07-13 09:21:31 KST [ISP.0090.0003C] BIS_ITS_Formation_BY100 [ BIS TO ITS ] # Service Start Time = 20200713 092131288
2020-07-13 09:21:31 KST [ISP.0090.0003C] BIS_ITS_Formation_BY100 [ BIS TO ITS ] # The service was consumed a 42 millisecond
2020-07-13 09:21:31 KST [ISP.0090.0003C] BIS_ITS_Formation_BY100 [ BIS TO ITS ] # Service End Time = 20200713 092131330
2020-07-13 09:21:31 KST [ISP.0090.0003C] BIS_ITS_Formation_BY100 [ BIS TO ITS ] ###################################################
2020-07-13 09:21:33 KST [ISP.0090.0003C] CMM_TLK_Talk_Send [ CMM TO TLK ] ###################################################
2020-07-13 09:21:33 KST [ISP.0090.0003C] CMM_TLK_Talk_Send [ CMM TO TLK ] # Service Start Time = 20200713 092133094
2020-07-13 09:21:33 KST [ISP.0090.0003C] CMM_TLK_Talk_Send [ CMM TO TLK ] # Total Count = 3
2020-07-13 09:21:33 KST [ISP.0090.0003C] CMM_TLK_Talk_Send [ CMM TO TLK ] # The service was consumed a 17 millisecond
2020-07-13 09:21:33 KST [ISP.0090.0003C] CMM_TLK_Talk_Send [ CMM TO TLK ] # Service End Time = 20200713 092133111
2020-07-13 09:21:33 KST [ISP.0090.0003C] CMM_TLK_Talk_Send [ CMM TO TLK ] ###################################################
2020-07-13 09:21:38 KST [ISP.0090.0003C] CMM_AML_Amail_Send_mysql [ CMM TO AML ] ###################################################
2020-07-13 09:21:38 KST [ISP.0090.0003C] CMM_AML_Amail_Send_mysql [ CMM TO AML ] # Service Start Time = 20200713 092138072
2020-07-13 09:21:38 KST [ISP.0090.0003C] CMM_AML_Amail_Send_mysql [ CMM TO AML ] # Total Count = 19
2020-07-13 09:21:38 KST [ISP.0090.0003C] CMM_AML_Amail_Send_mysql [ CMM TO AML ] # The service was consumed a 82 millisecond
2020-07-13 09:21:38 KST [ISP.0090.0003C] CMM_AML_Amail_Send_mysql [ CMM TO AML ] # Service End Time = 20200713 092138154
2020-07-13 09:21:38 KST [ISP.0090.0003C] CMM_AML_Amail_Send_mysql [ CMM TO AML ] ###################################################
2020-07-13 09:21:39 KST [ISP.0090.0003C] CMM_SMS_SMS_Send [ CMM TO EAI ] ###################################################
2020-07-13 09:21:39 KST [ISP.0090.0003C] CMM_SMS_SMS_Send [ CMM TO EAI ] # Service Start Time = 20200713 092139062
2020-07-13 09:21:39 KST [ISP.0090.0003C] CMM_SMS_SMS_Send [ CMM TO EAI ] # Total Count = 6
2020-07-13 09:21:39 KST [ISP.0090.0003C] CMM_SMS_SMS_Send [ CMM TO EAI ] # The service was consumed a 51 millisecond
2020-07-13 09:21:39 KST [ISP.0090.0003C] CMM_SMS_SMS_Send [ CMM TO EAI ] # Service End Time = 20200713 092139113
2020-07-13 09:21:39 KST [ISP.0090.0003C] CMM_SMS_SMS_Send [ CMM TO EAI ] ###################################################
2020-07-13 09:21:42 KST [ISP.0090.0003C] CMM_TLK_Talk_Send [ CMM TO TLK ] ###################################################
2020-07-13 09:21:42 KST [ISP.0090.0003C] CMM_TLK_Talk_Send [ CMM TO TLK ] # Service Start Time = 20200713 092142129
2020-07-13 09:21:42 KST [ISP.0090.0003C] CMM_TLK_Talk_Send [ CMM TO TLK ] # Total Count = 5
2020-07-13 09:21:42 KST [ISP.0090.0003C] CMM_TLK_Talk_Send [ CMM TO TLK ] # The service was consumed a 21 millisecond
2020-07-13 09:21:42 KST [ISP.0090.0003C] CMM_TLK_Talk_Send [ CMM TO TLK ] # Service End Time = 20200713 092142150
2020-07-13 09:21:42 KST [ISP.0090.0003C] CMM_TLK_Talk_Send [ CMM TO TLK ] ###################################################
2020-07-13 09:21:48 KST [ISP.0090.0003C] SRV_ESH_QnA_Register_Modify [ SRV TO ESH ] ###################################################
2020-07-13 09:21:48 KST [ISP.0090.0003C] SRV_ESH_QnA_Register_Modify [ SRV TO ESH ] # Service Start Time = 20200713 092148085
2020-07-13 09:21:48 KST [ISP.0090.0003C] SRV_ESH_QnA_Register_Modify [ SRV TO ESH ] # Total Head Count = 6
2020-07-13 09:21:48 KST [ISP.0090.0003C] SRV_ESH_QnA_Register_Modify [ SRV TO ESH ] # Total Detail Count = 6
2020-07-13 09:21:48 KST [ISP.0090.0003C] SRV_ESH_QnA_Register_Modify [ SRV TO ESH ] # The service was consumed a 102 millisecond
2020-07-13 09:21:48 KST [ISP.0090.0003C] SRV_ESH_QnA_Register_Modify [ SRV TO ESH ] # Service Start Time = 20200713 092148187
2020-07-13 09:21:48 KST [ISP.0090.0003C] SRV_ESH_QnA_Register_Modify [ SRV TO ESH ] ###################################################
2020-07-13 09:21:56 KST [ISP.0090.0003C] BIS_ESH_Broad_Order [ BIS TO ESH ] ###################################################
2020-07-13 09:21:56 KST [ISP.0090.0003C] BIS_ESH_Broad_Order [ BIS TO ESH ] # Service Start Time = 20200713 092156027
2020-07-13 09:21:56 KST [ISP.0090.0003C] BIS_ESH_Broad_Order [ BIS TO ESH ] # Total_Count = 30
2020-07-13 09:21:56 KST [ISP.0090.0003C] BIS_ESH_Broad_Order [ BIS TO ESH ] # The service was consumed a 359 millisecond
2020-07-13 09:21:56 KST [ISP.0090.0003C] BIS_ESH_Broad_Order [ BIS TO ESH ] # Service End Time = 20200713 092156386
2020-07-13 09:21:56 KST [ISP.0090.0003C] BIS_ESH_Broad_Order [ BIS TO ESH ] ###################################################
2020-07-13 09:22:04 KST [ISP.0090.0003C] CST_AML_Customer_Person [ CST TO AML ] ###################################################
2020-07-13 09:22:04 KST [ISP.0090.0003C] CST_AML_Customer_Person [ CST TO AML ] # Service Start Time = 20200713 092204071
2020-07-13 09:22:04 KST [ISP.0090.0003C] CST_AML_Customer_Person [ CST TO AML ] # Total Count = 17
2020-07-13 09:22:04 KST [ISP.0090.0003C] CST_AML_Customer_Person [ CST TO AML ] # The service was consumed a 162 millisecond
2020-07-13 09:22:04 KST [ISP.0090.0003C] CST_AML_Customer_Person [ CST TO AML ] # Service End Time = 20200713 092204233
2020-07-13 09:22:04 KST [ISP.0090.0003C] CST_AML_Customer_Person [ CST TO AML ] ###################################################                                                                                                                                   
$ vi test.awk


/Service Start Time = / {
service = $5;
ms[service] = substr($17, 7)
next
}
/# Total Count/ {
count[service] = $NF;
next
}
/# The service was consumed a / {
timestamp = $1 "T" $2 "." ms[service] "+09:00";
elapsed_ms = $17;
if ( service ) printf "%s host=%s service=%s count=%d elapsed_ms=%d\n", timestamp, host, service, count[service], elapsed_ms
fflush();
}
$ cat testlog2 | awk -v host=$( hostname ) -f test.awk

출력
2020-07-13T09:21:31.288+09:00 host=MacBook-Pro.local service=BIS_ITS_Formation_BY100 count=0 elapsed_ms=42
2020-07-13T09:21:33.094+09:00 host=MacBook-Pro.local service=CMM_TLK_Talk_Send count=3 elapsed_ms=17
2020-07-13T09:21:38.072+09:00 host=MacBook-Pro.local service=CMM_AML_Amail_Send_mysql count=19 elapsed_ms=82
2020-07-13T09:21:39.062+09:00 host=MacBook-Pro.local service=CMM_SMS_SMS_Send count=6 elapsed_ms=51
2020-07-13T09:21:42.129+09:00 host=MacBook-Pro.local service=CMM_TLK_Talk_Send count=5 elapsed_ms=21
2020-07-13T09:21:48.085+09:00 host=MacBook-Pro.local service=SRV_ESH_QnA_Register_Modify count=0 elapsed_ms=102
2020-07-13T09:21:56.027+09:00 host=MacBook-Pro.local service=BIS_ESH_Broad_Order count=0 elapsed_ms=359
2020-07-13T09:22:04.071+09:00 host=MacBook-Pro.local service=CST_AML_Customer_Person count=17 elapsed_ms=162