SW/리눅스

Linux : Awk 명령어, 예제, 사용 방법

얇은생각 2022. 8. 22. 07:30
반응형

Awk는 고급 텍스트 처리를 위해 설계된 범용 스크립트 언어입니다. 그것은 주로 보고 및 분석 도구로 사용됩니다.

절차적인 대부분의 다른 프로그래밍 언어와 달리, awk는 데이터 기반이므로 입력 텍스트에 대해 수행할 일련의 작업을 정의합니다. 입력 데이터를 가져와서 변환하고 결과를 표준 출력으로 보냅니다.

이 문서는 awk 프로그래밍 언어의 필수 요소를 다룹니다. awk의 기본을 알면 명령줄에서 텍스트 파일을 조작하는 능력이 크게 향상됩니다.

 

 

Linux : Awk 명령어, 예제, 사용 방법

 

 

awk 작동 방식

awk에는 몇 가지 다른 구현체가 있습니다. 우리는 gawk라고 불리는 awk의 GNU 구현을 사용할 것입니다. 대부분의 리눅스 시스템에서 awk 인터프리터는 gawk의 심볼 링크일 뿐입니다.

 

 

 

레코드 및 필드

Awk는 텍스트 데이터 파일과 스트림을 처리할 수 있습니다. 입력 데이터는 기록과 필드로 나뉩니다. Awk는 입력 끝에 도달할 때까지 한 번에 하나의 레코드에서 작동합니다. 레코드는 레코드 구분 기호라는 문자로 구분됩니다. 기본 레코드 구분 기호는 줄 바꿈 문자로, 텍스트 데이터의 각 행이 레코드임을 의미합니다. RS 변수를 사용하여 새 레코드 구분 기호를 설정할 수 있습니다.

레코드는 필드 구분자로 구분된 필드로 구성됩니다. 기본적으로 필드는 하나 이상의 탭, 공백 및 줄 바꿈 문자를 포함하여 공백으로 구분됩니다.

각 레코드의 필드는 1로 시작하는 달러 기호($)와 필드 번호로 참조됩니다. 첫 번째 필드는 $1로 표시되고 두 번째 필드는 $2로 표시되며 이러한 방식으로 표시됩니다. 마지막 필드는 특수 변수 $NF와 함께 참조할 수도 있습니다. 전체 레코드는 $0으로 참조할 수 있습니다.

다음은 레코드 및 필드를 참조하는 방법을 보여 주는 시각적 표현입니다.

# tmpfs      788M  1.8M  786M   1% /run/lock 
# /dev/sda1  234G  191G   31G  87% /
# |-------|  |--|  |--|   |--| |-| |--------| 
#    $1       $2    $3     $4   $5  $6 ($NF) --> fields
# |-----------------------------------------| 
#                     $0                     --> record

 

 

 

Awk 프로그램

awk로 텍스트를 처리하려면 명령어에 수행할 작업을 알려주는 프로그램을 작성합니다. 프로그램은 일련의 규칙과 사용자 정의 기능으로 구성됩니다. 각 규칙에는 하나의 패턴과 작업 쌍이 포함됩니다. 규칙은 줄 바꿈 또는 세미콜론(;)으로 구분됩니다. 일반적으로 awk 프로그램은 다음과 같습니다.

pattern { action }
pattern { action }
...

 

 

awk가 데이터를 처리할 때 패턴이 레코드와 일치하면 해당 레코드에 대해 지정된 동작을 수행합니다. 규칙에 패턴이 없으면 모든 레코드(줄)가 일치합니다.

awk 작업은 중괄호({})로 묶이고 문으로 구성됩니다. 각 문은 수행할 작업을 지정합니다. 동작은 줄 바꿈 또는 세미콜론(;)으로 구분된 둘 이상의 문을 가질 수 있습니다. 규칙에 작업이 없으면 기본적으로 전체 레코드를 인쇄합니다.

Awk는 식, 조건, 입력, 출력 문 등을 포함한 다양한 유형의 문을 지원합니다. 가장 일반적인 awk 문장은 다음과 같습니다.

 

exit - 전체 프로그램의 실행을 중지하고 종료합니다.

next - 현재 레코드 처리를 중지하고 입력 데이터의 다음 레코드로 이동합니다.

print - 레코드, 필드, 변수 및 사용자 정의 텍스트를 인쇄합니다.

printf - C 및 bash printf 와 마찬가지로 출력 형식을 보다 세부적으로 제어할 수 있습니다.

 

awk 프로그램을 작성할 때 해시 마크(#) 이후와 줄 끝까지의 모든 내용은 주석으로 간주됩니다. 긴 줄은 연속 문자 백슬래시(\)를 사용하여 여러 줄로 나눌 수 있습니다.

 

 

 

awk 프로그램을 실행

awk 프로그램은 여러 가지 방법으로 실행할 수 있습니다. 프로그램이 짧고 간단한 경우 명령줄을 통해 awk 인터프리터에 직접 전달할 수 있습니다.

awk 'program' input-file...

 

 

명령줄에서 프로그램을 실행할 때는 셸이 프로그램을 해석하지 않도록 작은 따옴표(')로 묶어야 합니다.

프로그램이 크고 복잡한 경우 파일을 파일로 저장하고 -f 옵션을 사용하여 파일을 awk 명령으로 전달하는 것이 가장 좋습니다.

awk -f program-file input-file...

# Bucks Milwaukee    60 22 0.732 
# Raptors Toronto    58 24 0.707 
# 76ers Philadelphia 51 31 0.622
# Celtics Boston     49 33 0.598
# Pacers Indiana     48 34 0.585

 

 

 

Awk 패턴

awk의 패턴은 관련 동작의 실행 여부를 제어합니다.

Awk는 정규식, 관계식, 범위, 특수식 패턴을 포함한 다양한 유형의 패턴을 지원합니다. 

규칙에 패턴이 없으면 각 입력 레코드가 일치합니다. 다음은 액션만 포함하는 규칙의 예입니다.

프로그램은 각 레코드의 세 번째 필드를 인쇄합니다.

awk '{ print $3 }' teams.txt

# 60
# 58
# 51
# 49
# 48

 

 

 

 

 

정규식 패턴

정규식 또는 정규식은 문자열 집합과 일치하는 패턴입니다. Awk 정규식 패턴은 슬래시(/)로 묶입니다.

/regex pattern/ { action }

 

 

가장 기본적인 예는 리터럴 문자 또는 문자열 일치입니다.

예를 들어, "0.5"가 포함된 각 레코드의 첫 번째 필드를 표시하려면 다음 명령을 실행합니다.

awk '/0.5/ { print $1 }' teams.txt

# Celtics
# Pacers

 

 

패턴은 확장 정규식의 모든 유형일 수 있습니다. 다음은 레코드가 두 자리 이상으로 시작하는 경우 첫 번째 필드를 인쇄하는 예입니다.

awk '/^[0-9][0-9]/ { print $1 }' teams.txt

# 76ers

 

 

 

관계식 패턴

관계식 패턴은 일반적으로 특정 필드 또는 변수의 내용을 일치시키는 데 사용됩니다.

기본적으로 정규식 패턴은 레코드와 일치합니다. 정규식을 필드와 일치시키려면 필드를 지정하고 패턴에 대해 "contain" 비교 연산자(~)를 사용하십시오.

예를 들어, 두 번째 필드에 "ia"가 포함된 각 레코드의 첫 번째 필드를 인쇄하려면 다음과 같이 입력합니다.

awk '$2 ~ /ia/ { print $1 }' teams.txt

# 76ers
# Pacers

 

 

지정된 패턴이 없는 필드를 일치시키려면 !~ 연산자를 사용합니다.

awk '$2 !~ /ia/ { print $1 }' teams.txt

# Bucks
# Raptors
# Celtics

 

 

큼, 작음, 같음 등의 관계에 대해 문자열 또는 숫자를 비교할 수 있습니다. 다음 명령은 세 번째 필드가 50보다 큰 모든 레코드의 첫 번째 필드를 인쇄합니다.

awk '$3 > 50 { print $1 }' teams.txt

# Bucks
# Raptors
# 76ers

 

 

 

범위 패턴

범위 패턴은 쉼표로 구분된 두 개의 패턴으로 구성됩니다.

pattern1, pattern2

 

 

첫 번째 패턴과 일치하는 레코드로 시작하여 두 번째 패턴과 일치하는 레코드가 나올 때까지 모든 레코드가 일치합니다.

다음은 "Rapters"를 포함한 레코드에서 "Celtics"를 포함한 레코드의 첫 번째 필드를 인쇄하는 예입니다.

awk '/Raptors/,/Celtics/ { print $1 }' teams.txt

# Raptors
# 76ers
# Celtics

 

 

패턴은 관계 표현일 수도 있습니다. 아래 명령은 4번째 필드가 32인 필드부터 4번째 필드가 33인 필드까지 모든 레코드를 인쇄합니다.

awk '$4 == 31, $4 == 33 { print $0 }' teams.txt

# 76ers Philadelphia 51 31 0.622
# Celtics Boston     49 33 0.598

 

 

범위 패턴은 다른 패턴 식과 결합할 수 없습니다.

 

 

 

특수 표현식 패턴

Awk에는 다음과 같은 특수 패튼이 포함되어 있습니다.

 

BEGIN - 레코드를 처리하기 전에 작업을 수행하는 데 사용됩니다.

END - 레코드를 처리한 후 작업을 수행할 때 사용합니다.

 

BEGIN 패턴은 일반적으로 계산과 같은 레코드의 데이터를 처리하기 위해 변수와 END 패턴을 설정하는 데 사용됩니다.

다음 예제에서는 "처리 시작"을 인쇄한 다음 각 레코드의 세 번째 필드를 인쇄하고 마지막으로 "처리 종료"를 인쇄합니다.:

awk 'BEGIN { print "Start Processing." }; { print $3 }; END { print "End Processing." }' teams.txt

# Start Processing
# 60
# 58
# 51
# 49
# 48
# End Processing.

 

 

프로그램에 BEGIN 패턴만 있으면 동작이 실행되며 입력이 처리되지 않습니다. 프로그램에 END 패턴만 있는 경우 규칙 작업을 수행하기 전에 입력이 처리됩니다.

또한 Gnu 버전의 awk에는 파일을 처리할 때 작업을 수행할 수 있는 두 가지 특수 패턴 BEGINFILE과 ENDFILE이 포함되어 있습니다.

 

 

 

패턴을 결합

Awk를 사용하면 논리 AND 연산자(&&)와 논리 OR 연산자(|)를 사용하여 둘 이상의 패턴을 결합할 수 있습니다.

다음은 && 연산자를 사용하여 세 번째 필드가 50보다 크고 네 번째 필드가 30보다 작은 레코드의 첫 번째 필드를 인쇄하는 예입니다.

awk '$3 > 50 && $4 < 30 { print $1 }' teams.txt

# Bucks
# Raptors

 

 

 

기본 제공 변수

Awk는 유용한 정보를 포함하는 많은 기본 제공 변수를 가지고 있으며 프로그램이 어떻게 처리되는지 제어할 수 있습니다. 다음은 가장 일반적인 기본 제공 변수입니다.

 

NF - 레코드에 있는 필드 수입니다.

NR - 현재 레코드의 번호입니다.

FILENAME - 현재 처리 중인 입력 파일의 이름입니다.

FS - 필드 구분자입니다.

RS - 구분 기호를 기록합니다.

OFS - 출력 필드 구분자입니다.

ORS - 출력 레코드 구분 기호입니다.

 

다음은 파일 이름과 줄(레코드) 수를 인쇄하는 방법을 보여주는 예입니다.

awk 'END { print "File", FILENAME, "contains", NR, "lines." }' teams.txt

# File teams.txt contains 5 lines.

 

 

AWK의 변수는 프로그램의 어느 라인에서나 설정할 수 있습니다. 전체 프로그램에 대한 변수를 정의하려면 해당 변수를 BEGIN 패턴으로 넣습니다.

 

 

 

필드 및 레코드 구분 기호를 변경

필드 구분자의 기본값은 공백 또는 탭 문자 수입니다. FS 변수에서 설정하여 변경할 수 있습니다.

예를 들어, 필드 구분 기호를 로 설정하려면 다음을 사용합니다.

awk 'BEGIN { FS = "." } { print $1 }' teams.txt

# Bucks Milwaukee    60 22 0
# Raptors Toronto    58 24 0
# 76ers Philadelphia 51 31 0
# Celtics Boston     49 33 0
# Pacers Indiana     48 34 0

 

 

필드 구분자는 둘 이상의 문자로 설정할 수도 있습니다.

awk 'BEGIN { FS = ".." } { print $1 }' teams.txt

 

 

명령줄에서 awk 한 줄을 실행할 때 -F 옵션을 사용하여 필드 구분 기호를 변경할 수도 있습니다.

awk -F "." '{ print $1 }' teams.txt

 

 

기본적으로 레코드 구분 기호는 줄 바꿈 문자이며 RS 변수를 사용하여 변경할 수 있습니다.

다음은 레코드 구분 기호를 로 변경하는 방법을 보여주는 예입니다.

awk 'BEGIN { RS = "." } { print $1 }' teams.txt

# Bucks Milwaukee    60 22 0
# 732 
# Raptors Toronto    58 24 0
# 707 
# 76ers Philadelphia 51 31 0
# 622
# Celtics Boston     49 33 0
# 598
# Pacers Indiana     48 34 0
# 585

 

 

 

Awk 동작

Awk 작업은 중괄호({})로 묶이고 패턴이 일치할 때 실행됩니다. 동작은 0개 이상의 문을 가질 수 있습니다. 여러 개의 문은 표시되는 순서대로 실행되며 줄 바꿈 또는 세미콜론(;)으로 구분되어야 합니다.

awk에서 지원되는 몇 가지 유형의 액션 문이 있습니다.

 

변수 할당, 산술 연산자, 증분 및 감소 연산자와 같은 식입니다.

프로그램 흐름을 제어하는 데 사용되는 제어 문(전환 중 등)입니다.

print 및 printf와 같은 문을 출력합니다.

복합 문을 사용하여 다른 문을 그룹화합니다.

입력 문, 입력 처리를 제어합니다.

Deletion 문, 배열 요소를 제거합니다.

 

인쇄문은 아마도 가장 많이 사용되는 awk 문일 것입니다. 텍스트, 레코드, 필드 및 변수의 형식화된 출력합니다.

여러 항목을 인쇄할 때는 쉼표로 구분해야 합니다. 다음은 예입니다.

awk '{ print $1, $3, $5 }' teams.txt

# Bucks 60 0.732
# Raptors 58 0.707
# 76ers 51 0.622
# Celtics 49 0.598
# Pacers 48 0.585

 

 

쉼표를 사용하지 않으면 항목 사이에 공백이 없습니다.

awk '{ print $1 $3 $5 }' teams.txt

# Bucks600.732
# Raptors580.707
# 76ers510.622
# Celtics490.598
# Pacers480.585

 

 

인수 없이 인쇄를 사용할 경우 기본적으로 $0이 인쇄됩니다. 현재 레코드가 인쇄됩니다.

사용자 정의 텍스트를 인쇄하려면 텍스트를 큰따옴표로 묶어야 합니다.

awk '{ print "The first field:", $1}' teams.txt

# The first field: Bucks
# The first field: Raptors
# The first field: 76ers
# The first field: Celtics
# The first field: Pacers

 

 

또한 줄 바꿈과 같은 특수 문자를 인쇄할 수 있습니다.

awk 'BEGIN { print "First line\nSecond line\nThird line" }'

# First line
# Second line
# Third line

 

 

printf 문을 통해 출력 형식을 보다 효과적으로 제어할 수 있습니다. 다음은 줄 번호를 삽입하는 예입니다.

awk '{ printf "%3d. %s\n", NR, $0 }' teams.txt

#   1. Bucks Milwaukee    60 22 0.732 
#   2. Raptors Toronto    58 24 0.707 
#   3. 76ers Philadelphia 51 31 0.622
#   4. Celtics Boston     49 33 0.598
#   5. Pacers Indiana     48 34 0.585

 

 

다음 명령은 각 행의 세 번째 필드에 저장된 값의 합계를 계산합니다.

awk '{ sum += $3 } END { printf "%d\n", sum }' teams.txt

# 266

 

 

다음은 식 및 제어문을 사용하여 1에서 5까지의 숫자 제곱을 인쇄하는 방법을 보여주는 또 다른 예입니다.

awk 'BEGIN { i = 1; while (i < 6) { print "Square of", i, "is", i*i; ++i } }'

# Square of 1 is 1
# Square of 2 is 4
# Square of 3 is 9
# Square of 4 is 16
# Square of 5 is 25

 

 

위 명령과 같은 한 줄 명령은 이해하고 유지하기가 더 어렵습니다. 긴 프로그램을 작성할 때는 별도의 프로그램 파일을 만들어야 합니다.

# prg.awk

BEGIN { 
  i = 1
  while (i < 6) { 
    print "Square of", i, "is", i*i; 
    ++i 
  } 
}

 

 

파일 이름을 awk 인터프리터에 전달하여 프로그램을 실행합니다.

awk -f prg.awk

 

 

shebang 지시문을 사용하고 awk 인터프리터를 설정하여 awk 프로그램을 실행 파일로 실행할 수도 있습니다.

# prg.awk

#!/usr/bin/awk -f
BEGIN { 
  i = 1
  while (i < 6) { 
    print "Square of", i, "is", i*i; 
    ++i 
  } 
}

 

 

파일을 저장하고 실행 파일로 만듭니다.

chmod +x prg.awk

 

 

이제 다음을 입력하여 프로그램을 실행할 수 있습니다.

./prg.awk

 

 

 

Awk 프로그램에서 Shell 변수를 사용

셸 스크립트에서 awk 명령을 사용할 경우 awk 프로그램에 셸 변수를 전달해야 할 수 있습니다. 한 가지 방법은 프로그램을 작은따옴표 대신 더블로 묶고 프로그램에서 변수를 대체하는 것입니다. 그러나 이 옵션은 당신이 awk 변수를 탈출해야 하므로 당신의 awk 프로그램을 더 복잡하게 만들 것입니다.

awk 프로그램에서 셸 변수를 사용하는 권장되는 방법은 셸 변수를 awk 변수에 할당하는 것입니다. 다음은 예입니다.

num=51
awk -v n="$num" 'BEGIN {print n}'

# 51

 

 

Awk는 텍스트 조작을 위한 가장 강력한 도구 중 하나입니다.

awk 프로그래밍 언어의 표면에 흠집이 거의 나지 않습니다. awk에 대한 자세한 내용은 공식 Gawk 문서를 참조하십시오.

 

 

 

참조

https://linuxize.com/post/awk-command/

반응형