_언어_는 AWK라고 하고, AWK 프로그램을 해석하는 _실행 파일_은 awk 또는 **gawk**라고 부를게요.
AWK 프로그램은 패턴-액션 쌍으로 이루어져 있어요.
pattern1 { action1 }
pattern2 { action2 }
...
패턴은 입력과 대조할 정규 표현식 패턴이 될 수 있어요. 참/거짓 값을 내놓는 어떤 표현식이든 될 수도 있어요.
액션은 하나 이상의 AWK 명령이에요. 감싸는 중괄호는 반드시 필요해요.
패턴의 결과가 _참_이면, 그에 해당하는 액션이 실행돼요.
AWK는 입력을 일련의 레코드로 읽어요. 각 레코드는 다시 0개 이상의 필드로 나뉘어요.
기본 동작은 이래요.
패턴은 생략할 수 있어요. 그러면 액션이 _모든 입력 레코드_에 대해 실행돼요.
액션도 생략할 수 있어요. 그러면 기본 동작으로 현재 레코드를 출력해요.
자주 쓰이는 특수한 패턴이 두 가지 있어요.
BEGIN은 입력을 하나도 읽기 전에 연결된 액션을 실행해요.END는 모든 입력을 다 읽은 뒤에 연결된 액션을 실행해요.필드는 $1, $2, $3 등으로 가리켜요.
현재 레코드는 $0이에요.
분명히 해두자면, 이것들은 엄밀히 말해 "변수"가 아니에요.
$는 주어진 필드 번호의 값을 가져오는 _연산자_라고 볼 수 있어요.
이 부분은 이후 개념에서 더 자세히 살펴봐요.
그 밖에 자주 쓰이는 내장 변수도 있어요.
RS는 입력 레코드 구분자예요.
앞에서 말했듯이 기본값은 줄 바꿈이에요.FS는 입력 필드 구분자예요.이 변수들은 보통 BEGIN 액션 블록에서 설정해요.
이 변수들은 프로그램이 실행되는 동안 AWK가 자동으로 설정해요.
NF는 현재 레코드의 필드 개수를 저장해요.
$NF를 사용해요.NR은 현재 레코드 번호를 저장해요.
NR이 지금까지 처리한 전체 레코드 수를 담아요.FNR은 현재 입력 파일에서의 레코드 번호를 저장해요.
NR == FNR {action}
이것은 "누적 레코드 번호가 현재 파일의 레코드 번호와 같으면"이라는 뜻이에요.
이 조건은 _첫 번째 입력 파일_의 레코드에서만 참이 될 수 있어요.AWK는 C와 참과 거짓을 판정하는 개념이 같아요.
0은 거짓이에요.AWK는 텍스트를 다루는 언어라서, 참/거짓 판정이 문자열에도 확장돼요.
""은 거짓이에요.AWK는 C와 참과 거짓을 판정하는 개념이 같아요
AWK는 1970년대에 Bell Labs에서 만들어졌는데, C가 탄생한 것과 같은 환경이었어요. C는 AWK의 문법에 큰 영향을 주었어요.
주의해야 할 이상한 점이 하나 있어요
0은 거짓이에요."0"은 참이에요!AWK의 데이터 타입은 다음 개념들에서 더 다뤄요.
주석은 # 문자로 시작하고 줄 끝까지 이어져요.
awk에 입력을 주는 방법awk는 파일이나 표준 입력에서 입력을 읽을 수 있어요.
다음 방법이 모두 잘 동작해요.
awk '/regex/ {print $1}' file1 file2 ...
awk '/regex/ {print $1}' < file
some_command_here | awk '/regex/ {print $1}'
유닉스 계열 시스템에서 /etc/passwd에는 사용자 정보가 들어 있어요.
각 사용자는 한 줄씩 따로 설명되고, 필드는 콜론으로 구분돼요.
사용자 이름을 나열하려면 이렇게 해요.
awk '
BEGIN { FS = ":" }
{ print $1 }
' /etc/passwd
{print $1} 액션에는 패턴이 없어서, 모든 레코드에 대해 실행된다는 점을 눈여겨봐요.
로그인 셸로 bash를 사용하는 사용자만 출력하고 싶다면 이렇게 하면 돼요.
awk '
BEGIN { FS = ":" }
$7 == "/bin/bash" { print $1 }
' /etc/passwd
다른 흔한 유닉스 명령과 같은 결과를 내는 awk 프로그램도 있어요.
파일 내용 출력하기
cat file.txt
awk '1' file.txt
파일에서 패턴 찾기
grep 'foo.*bar' file.txt
awk '/foo.*bar/' file.txt
파일 앞부분에서 몇 줄만 출력하기
head -n 20 file.txt
awk '
1
NR == 20 {exit}
' file.txt
파일에서 텍스트 바꾸기
sed 's/foo/bar/' file.txt
awk '{sub(/foo/, "bar")};1' file.txt
# or more readably
awk '
{
sub(/foo/, "bar")
print
}
' file.txt