앞으로의 포스팅 진행 방향입니다. sed나 배열을 포스팅하고 싶었으나 비중을 awk에 몰고 후에 스크립트를 분석하는 것으로 몰았습니다. 스킬 향상은 상대적으로 후자에서 더 많이 보여질 것으로 예상하고 있고 분석 중 전자의 경우가 나올 때 주석이나 밑에 설명을 적으려고 합니다.
awk는 파일로부터 레코드(record)를 선택하고 데이터를 분류한 다음, 선택된 레코드에 포함된 값을 조작하거나 데이터화하는 것을 목적으로 사용하는 프로그램입니다. 즉, 데이터를 내가 원하는 포맷대로 쉽게 가공할 수 있도록 도와주고 그 결과를 행과 열로 출력해주는 일을 합니다.
프로그램이라 명한 이유는 "awk programming language"라는 프로그래밍 언어로 작성된 프로그램을 실행하는 명령어이기 때문입니다.
출력 라인을 포맷, 조건 및 루프, 산술 및 문자열 연산에 이용됩니다.
이렇게만 작성하면 '그래서 정확히 어떤 일인데?' 하실 수 있습니다.
흰색 박스로 묶은 부분은 레이블이 되고 레이블 안 공백(Space, Tab)을 기점으로 필드라 명명됩니다.
awk [옵션] 패턴 {액션}
[파일]
패턴과 옵션은 생략도 되고 여러 개 사용도 가능합니다. 다만
패턴을 생략하는 경우는 "모든 레코드"가 적용되고, 액션을 생략하면 "print"가 적용됩니다.
백문이 불여일견. 바로 예시로 넘어가서 설명드리겠습니다.
# pattern 생략.
$ awk '{ print }' ./file.txt # file.txt의 모든 레코드 출력.
# action 생략.
$ awk '/j/' ./file.txt # file.txt에서 j를 포함하는 레코드 출력
#file.txt에서는 j가 들어간 3번 도요타의 레이블이 출력됩니다.
#그렇다면 밑의 출력은 어떤 명령을 입력하여 나왔을지 한 번 생각해보세요!
Name Country
KIA Korea
Volvo Sweden
Toyata Japen
Ferrari Italy
Ford USA
# a가 들어간 라인을 카운팅한 후 출력합니다.
$ awk '/a/{++cnt} END {print "Count = ", cnt}' file.txt
# Count = 4
BEGIN/END란? END 이전의 액션과 패턴을 BEGIN, 이후의 액션을 END라 합니다.
현재 /a/{++cnt}이 BEGIN에 해당되고 BEGIN을 처리해야 END의 액션이 정상적으로 이루어집니다.
# awk를 이용해 해당 레코드의 첫 번째 열과 마지막 열을 가져와 출력합니다.
$ df -kPF xfs | awk '/boot/ {print $1, $NF}'
/dev/nvme0n1p1 /boot
#위 명령과 차이점은 -F: 입니다. 필드 구분 문자를 공백 말고 ":" 로 설정하게 됩니다.
#직접 명령어를 입력해보면서 -F를 넣지 않았을 때 또한 보면 좋겠습니다.
$ head -5 /etc/passwd | awk -F: '/root/ {print $1,$NF}'
root /bin/bash
#길이가 20이 넘는 레이블을 >(리다이렉션)을 이용해 result.txt에 저장합니다.
$ awk 'length($0) > 20' file.txt > result.txt
$ cat result.txt
Item Name Country cost
2 Volvo Sweden $4000
3 Toyata Japen $3000
4 Ferrari Italy $10000
파일을 만들어서 내용을 기입하고 output에 해당하는 결과를 얻어내는 과정을 통해 조건문을 학습하겠습니다.
조건에 따라 출력을 달리 해야하니 이를 구분하는 if가 필요하겠습니다.
# Question 1
A 25 27 50
B 35 75
C 75 78
D 99 88 76
#output
Not all scores are available for B
Not all scores are available for C
# Question 2
A 25 27 50
B 35 37 75
C 75 78 80
D 99 88 76
#output
A : Fail
B : Fail
C : Pass
D : Pass
Question 1
$ cat Quest1.txt | awk '(length($4)==0){print "Not all scores are available for",$1}'
Question 2
$ awk -f Q2.awk ./Quest2.txt $ cat Q2.awk awk { if ( $2 > 50 && $3 > 50 && $4 > 50 ) print $1 " : Pass"; else print $1 " : Fail"; }
$ cat disk_total.awk
BEGIN {
print "\n----- STORAGE TOTAL USAGE INFO -----\n"
}
{
SIZE += $2;USED += $3 #BEGIN과 END 사이에 있어 BODY라고도 합니다.
}
END {
print "Total Capacity \t= " SIZE/1024 " Mbytes"
print "USAGE \t\t= " USED/1024 " Mbytes"
print "\n----- END -----\n"
}
$ df -kPF xfs | awk -f disk_total.awk
----- STORAGE TOTAL USAGE INFO -----
Total Capacity = 33762.7 Mbytes
USAGE = 6427.23 Mbytes
----- END -----
https://www.hackerrank.com/challenges/awk-1/problem?h_r=internal-search