OS_Linux&Unix

[Linux/Unix] awk 명령어

최선을 다하자! 2022. 10. 20. 16:49

awk는 프로그래밍언어로 만들어져서 사용법이 매우... 까다로운 것 같다.

 

 

awk programming language

awk 명령어 옵션.

awk 명령의 기본 형식과 옵션

    awk [OPTION...] [awk program] [ARGUMENT...]
      OPTION
        -F        : 필드 구분 문자 지정.
        -f        : awk program 파일 경로 지정.
        -v        : awk program에서 사용될 특정 variable값 지정.
      awk program
        -f 옵션이 사용되지 않은 경우, awk가 실행할 awk program 코드 지정.
      ARGUMENT
        입력 파일 지정 또는 variable 값 지정.

 

 

awk 사용 예 명령어 옵션

파일의 전체 내용 출력 awk '{ print }' [FILE]
필드 값 출력 awk '{ print $1 }' [FILE]
필드 값에 임의 문자열을 같이 출력 awk '{print "STR"$1, "STR"$2}' [FILE]
지정된 문자열을 포함하는 레코드만 출력 awk '/STR/' [FILE]
특정 필드 값 비교를 통해 선택된 레코드만 출력 awk '$1 == 10 { print $2 }' [FILE]
특정 필드들의 합 구하기 awk '{sum += $3} END { print sum }' [FILE]
여러 필드들의 합 구하기 awk '{ for (i=2; i<=NF; i++) total += $i }; END { print "TOTAL : "total }' [FILE]
레코드 단위로 필드 합 및 평균 값 구하기 awk '{ sum = 0 } {sum += ($3+$4+$5) } { print $0, sum, sum/3 }' [FILE]
필드에 연산을 수행한 결과 출력하기 awk '{print $1, $2, $3+2, $4, $5}' [FILE]
레코드 또는 필드의 문자열 길이 검사 awk ' length($0) > 20' [FILE]
파일에 저장된 awk program 실행 awk -f [AWK FILE] [FILE]
필드 구분 문자 변경하기 awk -F ':' '{ print $1 }' [FILE]
awk 실행 결과 레코드 정렬하기 awk '{ print $0 }' [FILE]
특정 레코드만 출력하기 awk 'NR == 2 { print $0; exit }' [FILE]
출력 필드 너비 지정하기 awk '{ printf "%-3s %-8s %-4s %-4s %-4s\n", $1, $2, $3, $4, $5}' [FILE]
필드 중 최대 값 출력 awk '{max = 0; for (i=3; i<NF; i++) max = ($i > max) ? $i : max ; print max}' [FILE]

 

 

 

3.1 파일의 전체 내용 출력.

awk 파일에 "print" 액션만 지정한 경우, 입력으로 지정된 파일의 내용을 출력합니다.

 

$ awk '{ print }' ./file.txt            > file.txt의 전체 파일 내용 출력.
$ cat file.txt
1 ppotta 30 40 50
2 soft   60 70 80
3 prog   90 10 20
$ awk '{ print }' ./file.txt
1 ppotta 30 40 50
2 soft   60 70 80
3 prog   90 10 20

3.2 필드 값 출력.

"print $n" 액션을 통해 n번째 필드 값을 출력할 수 있습니다. 참고로, "$0"은 전체 레코드를 나타내는 변수입니다.

 

$ awk '{ print $2 }' ./file.txt           > 두 번째 필드 값 출력.
$ awk '{ print $1,$2 }' ./file.txt        > 첫 번째, 두 번째 필드 값 출력.
$ awk '{ print $0}' ./file.txt            > 레코드 출력.
$ cat file.txt
1 ppotta 30 40 50
2 soft   60 70 80
3 prog   90 10 20
$ awk '{ print $1, $2}' ./file.txt
1 ppotta
2 soft
3 prog

3.3 필드 값에 임의 문자열을 같이 출력.

awk '{print "no:"$1, "user:"$2}' ./file.txt
$ cat file.txt
1 ppotta 30 40 50
2 soft   60 70 80
3 prog   90 10 20
$ awk '{print "no:"$1, "user:"$2}' ./file.txt
no:1 user:ppotta
no:2 user:soft
no:3 user:prog

3.4 지정된 문자열을 포함하는 레코드만 출력.

awk의 패턴에 정규 표현식(Regular Expression)을 사용하여 문자열 패턴을 검사할 수 있습니다. 이 때, 정규 표현식은 "/regex/" 형태로 지정할 수 있습니다.

 

awk '/pp/' ./file.txt                   # "pp" 가 포함된 레코드만 유효.
awk '/[2-3]0/' ./file.txt               # 20, 30 이 포함된 레코드만 유효.
$ cat file.txt
1 ppotta 30 40 50
2 soft   60 70 80
3 prog   90 10 20
$ awk '/pp/' ./file.txt
1 ppotta 30 40 50
$ awk '/[2-3]0/' ./file.txt
1 ppotta 30 40 50
3 prog   90 10 20

3.5 특정 필드 값 비교를 통해 선택된 레코드만 출력.

awk program language의 표현식을 사용하여, 유효한 레코드를 위한 필드 값을 비교할 수 있습니다.

 

awk '$1 == 2 { print $2 }' ./file.txt   # 첫 번째 필드가 2인 레코드의 두 번째 필드 출력.
awk '$3 > 70 { print $0 }' ./file.txt   # 세 번째 필드가 70보다 큰 레코드 출력.
awk '$3 == 30 && $4 ==40 { print $2 }' file.txt   # 세 번째 필드가 30이고 네 번째 필드가 40인 레코드의 두 번째 필드 출력.
$ cat file.txt
1 ppotta 30 40 50
2 soft   60 70 80
3 prog   90 10 20
$ awk '$1 == 2 { print $2 }' ./file.txt
soft
$ awk '$3 > 70 { print $0 }' ./file.txt
3 prog   90 10 20
$ awk '$3 == 30 && $4 ==40 { print $2 }' file.txt
ppotta

3.6 지정된 필드의 값을 더한 값 출력. (특정 필드에 대한 합 구하기)

awk program에서 변수의 사용을 통해 특정 필드의 값을 더하고, 더해진 총 합을 출력할 수 있습니다. 이 때, 총합은 모든 레코드 탐색이 끝난 시점인, "END" 패턴의 액션에서 실행합니다.

 

awk '{sum += $3} END { print sum }' ./file.txt
$ cat file.txt
1 ppotta 30 40 50
2 soft   60 70 80
3 prog   90 10 20
$ awk '{sum += $3} END { print "SUM : "sum }' ./file.txt
SUM : 180

3.7 여러 필드의 값을 더한 값 출력. (여러 필드에 대한 합 구하기)

for 루프를 수행하여 여러 필드의 값을 연산에 포함시킬 수 있습니다. 참고로 아래 예제에서 "NF"는 현재 레코드의 필드 갯수를 뜻하며, "$i"는 변수 i가 매핑된 필드를 뜻합니다. (i=2일 때 $2)

 

awk '{ for (i=2; i<=NF; i++) total += $i }; END { print "TOTAL : "total }' ./file.txt
$ cat file.txt
1 ppotta 30 40 50
2 soft   60 70 80
3 prog   90 10 20
$ awk '{ for (i=2; i<=NF; i++) total += $i }; END { print "TOTAL : "total }' ./file.txt
TOTAL : 450

3.8 레코드 단위로 필드 합 및 평균 값 구하기.

변수 및 액션을 조합하여 레코드 단위로 필드들의 값 및 평균을 계산하여 출력할 수 있습니다.

 

awk '{ sum = 0 } {sum += ($3+$4+$5) } { print $0, sum, sum/3 }' ./file.txt
$ cat file.txt
1 ppotta 30 40 50
2 soft   60 70 80
3 prog   90 10 20
$ awk '{ sum = 0 } {sum += ($3+$4+$5) } { print $0, sum, sum/3 }' ./file.txt
1 ppotta 30 40 50 120 40
2 soft   60 70 80 210 70
3 prog   90 10 20 120 40

3.9 필드에 연산을 수행한 결과 출력하기.

awk program 표현식을 사용하여, 필드에 연산을 수행한 결과를 출력할 수 있습니다.

 

awk '{print $1, $2, $3+2, $4, $5}' ./file.txt     # 세 번째 필드에 2를 더한 값을 출력.
$ cat file.txt
1 ppotta 30 40 50
2 soft   60 70 80
3 prog   90 10 20
$ awk '{print $1, $2, $3+2, $4, $5}' ./file.txt
1 ppotta 32 40 50
2 soft 62 70 80
3 prog 92 10 20

3.10 레코드 또는 필드의 문자열 길이 검사.

length() 함수를 사용해 레코드 또는 필드의 문자열 길이를 확인할 수 있습니다.

 

awk ' length($0) > 20' ./file.txt               # 레코드의 길이가 20보다 큰 경우.
awk ' length($2) > 4 { print $0 } ' ./file.txt  # 두 번째 필드의 길이가 4보다 큰 레코드 출력.
$ cat file.txt
1 ppotta 30 40 50
2 soft   60 70 80
3 prog   90 10 20
$ awk ' length($2) > 4 { print $0 } ' ./file.txt
1 ppotta 30 40 50

3.11 파일에 저장된 awk program 실행.

awk 실행 시, "-f" 옵션을 사용하여 파일로부터 awk program을 실행할 수 있습니다.

 

awk -f awkp.script ./file.txt           # awkp.script에 저장된 awk program 실행
$ cat file.txt
1 ppotta 30 40 50
2 soft   60 70 80
3 prog   90 10 20
$ cat awkp.script
{
    for (i=2; i<=NF; i++)
        total += $i
}

END {
    print "TOTAL : "total
}
$ awk -f awkp.script ./file.txt
TOTAL : 450

3.12 필드 구분 문자 변경하기.

기본적으로 레코드의 필드를 구분하는 문자는 space 입니다. 이를 "-F" 사용하여 변경할 수 있습니다.

 

awk -F ':' '{ print $1 }' ./file.txt         # 필드 구분 문자를 : 로 변경.
awk -F ',' '{ print $1 }' ./file.txt         # 필드 구분 문자를 , 로 변경.
$ cat file2.txt
1, ppotta, 30, 40, 50
2, soft,   60, 70, 80
3, prog,   90, 10, 20
$ awk -F ',' '{ print $1 }' ./file2.txt
1
2
3

3.13 awk 실행 결과 레코드 정렬하기.

awk 명령과 sort 명령을 조합하여, awk 실행 결과로 출력되는 레코드를 정렬할 수 있습니다.

 

awk '{ print $0 }' file.txt | sort      # 출력 레코드를 오름차순으로 정렬.
awk '{ print $0 }' file.txt | sort -r   # 출력 레코드를 역순으로 정렬.
$ cat file.txt
1 ppotta 30 40 50
2 soft   60 70 80
3 prog   90 10 20
$ awk '{ print $0 }' file.txt | sort -r
3 prog   90 10 20
2 soft   60 70 80
1 ppotta 30 40 50

3.14 특정 레코드만 출력하기.

exit 키워드를 사용하여, 조건에 따라 awk 실행을 중지시킬 수 있습니다.

 

awk '{ print $0; exit }' file.txt       # 첫 번째 레코드만 출력하고 실행 중지.
awk 'NR == 2 { print $0; exit }' file.txt         # 두 번째 레코드만 출력하고 실행 중지.
$ cat file.txt
1 ppotta 30 40 50
2 soft   60 70 80
3 prog   90 10 20
$ awk 'NR == 2 { print $0; exit }' file.txt
2 soft   60 70 80

3.15 출력 필드 너비 지정하기.

printf 함수를 사용하여 필드 값 출력 포맷을 지정할 수 있습니다. printf 함수에 사용하는 출력 포맷은 C 언어와 동일합니다.

 

awk '{ printf "%-3s %-8s %-4s %-4s %-4s\n", $1, $2, $3, $4, $5}' file.txt
$ cat file.txt
1 ppotta 30 40 50
2 soft   60 70 80
3 prog   90 10 20
$ awk '{ printf "%-3s %-8s %-4s %-4s %-4s\n", $1, $2, $3, $4, $5}' file.txt
1   ppotta   30   40   50  
2   soft     60   70   80  
3   prog     90   10   20

3.16 필드 중 최대 값 출력.

아래와 같은 코드를 통해 레코드 내 필드의 최대 값을 구하여 출력할 수 있습니다.

 

awk '{max = 0; for (i=3; i<=NF; i++) max = ($i > max) ? $i : max ; print max}' ./file.txt
$ cat file.txt
1 ppotta 30 40 50
2 soft   60 70 80
3 prog   90 10 20
$ awk '{max = 0; for (i=3; i<=NF; i++) max = ($i > max) ? $i : max ; print max}' ./file.txt
50
80
90

 

 

명료하게 잘 정리된 것이 있어 스크랩해왔습니다. 

 

 

출처

 

https://recipes4dev.tistory.com/171

 

리눅스 awk 명령어 사용법. (Linux awk command) - 리눅스 파일 텍스트 데이터 검사, 조작, 출력.

1. awk 명령어. 대부분의 리눅스 명령들이, 그 명령의 이름만으로 대략적인 기능이 예상되는 것과 다르게, awk 명령은 이름에 그 기능을 의미하는 단어나 약어가 포함되어 있지 않습니다. awk는 최

recipes4dev.tistory.com