데이터를 조작하고 리포트를 생성하기 위해 사용하는 언어이다.
awk 'pattern' filename
awk '{action}' filename
awk 'pattern {action}' filename
우선 vi를 통해 아래와 같은 내용의 awkfile을 생성해보자

awk '/길동/' awkfile

awk '{print $1}' awkfile
✍ 출력 명령에서 $1은 첫 번째 나오는 필드를 의미
필드는 공백단위로 구분된다.

awk '/홍/{print $1, $2}' awkfile

awk는 명령어로부터 입력을 받기 위해서 | 파이프기호를 사용할 수 있다.
command | awk 'pattern'
command | awk '{action}'
command | awk 'pattern {action}'
df | awk '$4 > 400000'

printf 함수는 포매팅이 필요없이 간단히 출력하는데 사용됨
printf 함수는 아규먼트로 변수와 계산된 값 또는 문자열 상수를 받는다.문자열은 큰 따옴표("")로 둘러싸야 한다
콤마는 아규먼트를 분리하는데 사용된다.
awk '/정/{print "\t\t안녕하세요? " $1, $2 " 님!"}' awkfile

awk 액션과 명령이 파일에 작성되어 있다면 -f 옵션을 사용함
awk 명령을 특정한 파일에 저장해두고 이 파일에 입력된 명령을 사용하여 다른 파일을 처리하고자 할 때 사용하는 것이 -f 옵션이다.
awk -f [awk 명령파일][awk 명령을 적용할 텍스트 파일]
예제 전에 awkcommand 파일에 아래와 같은 내용을 입력해두자

awk -f awkcommand awkfile
awkfile 을 awkcommand 형식으로 결과를 내라는 의미

- awk는 입력데이터를 볼 수 없지만 포맷 또는 구조는 볼 수 있음. 기본적으로 레코드라고 불리는 각 라인은 캐리지 리턴(newline)으로 분리된다.
- 모든 레코드는 awk에서 $0로 참조된다.
awk는 디폴트로 print액션만 사용해도 모든 레코드를 출력해준다.

각 레코드들의 번호는 awk의 빌트인 변수 NR에 저장됨
레코드가 저장된 다음 NR의 값은 하나씩 증가된다.

- 각 레코드는 디폴트로 공백이나 탭으로 분리된 필드라는 워드로 구성된다.
- 각 워드들은 하나의 필드라고 부르며 awk는 빌트인 변수인 NF에 필드의 수를 유지한다.
NF의 값은 일반적으로 라인당 100개의 필드를 가질 수 있다.
여태까지 쓰던 $1 $2는 필드를 호출하는 녀석이다.

awk 패턴은 awk가 입력 라인에 어떤 액션을 할 것인지 관리한다.
- 이 패턴은 정규표현식, 참과 거짓 상태의 결과 또는 이드르이 결합으로 구성되어 있음
- 디폴트 액션은 표현식이 참의 상태인 각 라인을 출력하는 것임
awk '/정 약용/{print $0}' awkfile
혹은
awk '/정 약용/' awkfile
awk '$3 < 6000' awkfile
- awk에서 액션은 컬리 브레이스({})로 둘러싸인 문장이며 세미콜론(;)으로 구분된다.
- 패턴은 액션 앞에 오며 액션은 간단한 문장 또는 복잡한 문장들의 그룹으로 만들 수 있다.
- 문장들은 세미콜론(;) 또는 newline에 의해 분리된다.
pattern{ action statement; action statement; etc. }
또는
pattern{
action statement
action statement
}
awk '/정 약용/{print "안녕하세요,"$1, $2 "님"}' awkfile

액션이 없는 패턴은 패턴과 매칭되는 모든 라인을 출력한다.
문자열 매칭 패턴은 슬래시(/)로 둘러싸인 정규 표현식을 포함함

awk에서 정규 표현식은 슬래시(/)로 둘러싸인 문자들로 구성된 패턴이다.
- 입력 라인에서의 문자열은 정규 표현식으로 매칭되고 결과 상태는 참이며, 표현식과 연관된 액션들이 실행된다.
- 지정된 액션이 없고 정규 표현식에 의해 매칭된 라인이 검색되며 레코드 라인 전체가 출력됨.

awk '/^정/{print $1,$2,$3}' awkfile

awk '/^[A-Z][a-z]+ /' awkfile2
틸드(~)로 표기되는 match 연산자는 하나의 레코드 또는 필드 안에서 표현식과 매칭되는 것이 있는지 검사하는 연산자이다.
awk '$2 ~ / [Kk]il/' awkfile2
awk '$2 !~ /g$/' awkfile2
- 여러 개의 awk 패턴과 액션을 사용하고자 할 경우에는 스크립트 문장을 입력하여 사용한다.
- 스크립트는 awk 코멘트와 문장을 포함하고 있는 파일이다.
vi awkcommand2
/동/{printf "안녕하세요! " $1, $2"님"}
/성계/{print NR "번 라인: "$0}; /^정/{print "'정'으로 시작되는 이름은 : " $1, $2}}

비교 표현식은 어떤 상태가 참일 때만 액션이 수행되는 라인을 검색한다.
이 표현식은 관계 연산자를 사용하고 숫자나 문자열을 비교할 때 사용
awk '$3 == 8683' awkfile
awk '$3 > 7000{print $1, $2}' awkfile
awk '$2 !~ /꺽정/' awkfile
name="Tom" #name 변수는 문자열
x++ #x변수는 숫자이며 0으로 초기화되고 1 증가함
number=100 #number 변수는 숫자임
name+0
number " "
사용자 정의형 변수는 awk에서 따로 정의하지 않는다.
awk '$1 ~ /이/{sum=$3 +$5; print sum}' awkfile

awk 'BEGIN{x=1; y=x++; print x, y}'
# 결과
2 1
awk 'BEGIN{x=1; y=++x; x, y}'
# 결과
2 2
BEGIN 패턴은 awk가 입력 파일의 라인을 처리하기 이전에 실행되어 액션 블록 앞에 놓인다.
BEGIN 블록은 awk가 BEGIN 액션 블록이 완료될 때까지 입력을 읽어 들이지 않기 때문에 입력 파일 없이 테스트 가능함
END 패턴은 어떤 입력 라인과도 매칭되지 않으나 END 패턴과 연관된 액션들을 실행한다.
- END 패턴은 입력의 모든 라인이 처리된 후에 처리된다.
getline 함수는 표준 입력, 파이프, 현재 처리되고 있는 파일로부터 입력을 읽기 위해 사용한다.
awk 'BEGIN{"date" | getline d; print d}'

awk 프로그램에서 파이프를 오픈할 때 또 다른 파이프를 오픈하기 전에 기존 파이프는 닫아주어야 한다.
- 파이프 심볼의 오른쪽 명령은 큰따옴표(" ")로 둘러쌈
awk '{print $1 | "sort -r"}' cars
awk 프로그램에서 파일이나 파이프를 다시 읽고 쓰기 위해서는 첫 번째 파이프는 닫아주어야 한다.
- 스크립트가 끝날 때 까지 오픈된 상태로 남아 있기 때문
- 첫 번째 라인에 있는 END 블록은 앞서 사용한 파이프를 닫아주는 역할을 한다.
awk '{print $1 | "sort -r"} END{close("sort -r")}' cars

system 함수는 아규먼트를 포함한 리눅스 시스템 명령들을 실행하여 awk 프로그램에게 종료상태를 리턴해준다.
- 리눅스 명령은 반드시 큰따옴표(" ")로 감싸주어야 한다.
vi awkscript
{
system("cat" $1)
}
awk -f awkscript awktext
while 루프에서는 먼저 임의의 변수에 초기값을 젖아함
- 이 값은 while문의 조건 표현식에서 테스트된다.
- 표현식이 참이면 루프 아래의 문장들을 실행함
- 실행할 문장의 수가 많다면 { }로 감싸줘야 한다.
awk '{i = 1; while ( i <= NF ) {print NF, $1; i++}}' awkdata
for 루프는 괄호 안에 초기화 표현식, 테스트 표현식, 테스트 표현식의 변수를 업데이트 하기 위한 표현식과 같은 3개의 표현식을 사용하며 각 표현식은 세미콜론으로 분리한다
vi awkscripts2
{
for(i = 1; i <= NF; i++)
if ($i < 0) {
print "0보다 작은 값 발견 = " $i; break
}
}
next 문장은 입력 파일로부터 입력의 다음 라인을 가져오고 awk 스크립트의 시작부터 다시 실행한다.

이런식으로 쓰는데 아마 거의 안쓰지 않을까 싶다.
아래처럼 해도 같은 결과가 나오고 훨씬 간결해지니깐..
고로 시험에도 안나오지 않을까? 히힣
if( $1 !~ /Jane/ ) {print}
awk의 빌트인 내장함수인 split 함수는 단어와 배열에 저장된 문자열을 자르기 위해 사용한다.
split(문자열, 배열, 필드 분리자)
split(문자열, 배열)
awk 'BEGIN{split("2023/7/21", date, "/");
print "오늘은 " date[1] "년" date[2] "월" date[3] "일입니다."}'
배열의 요소를 제거
awk 'BEGIN{split("2023/7/21", date, "/"); delete date[1];
print "오늘은 " date[1] "년" date[2] "월" date[3] "일입니다."}'
- sub 함수는 레코드에서 정규표현식에 매칭되는 문자열을 찾아서 원하는 문자열로 치환하는 기능을 수행
- 이 때 치환은 각 라인에서 가장 먼저 매칭되는 하나의 문자만 치환
- 매칭되는 문자열 모두를 치환하려면 gsub 함수를 사용


index 함수는 문자열에서 substring이 발견되는 첫 번째 위치를 리턴
index(string, substring)
awk 'BEGIN{print index("hello","lo")}'
length 함수는 문자열에서 문자의 개수를 리턴한다
아규먼트 없이 사용하려면 length 함수의 한 레코드의 문자 개수를 리턴함
length(문자열)
length

substr 함수는 주어진 문자열로부터 지정된 시작 위치의 앞까지 모두 자른 다음 남아있는 문자열을 리턴
substr(문자열, 시작 위치)
substr(문자열, 시작 위치, 문자열 길이)

match 함수는 정규표현식에 매칭되는 문자열이 있는 곳의 인덱스를 리턴한다
match(문자열, 정규표현식)

영어로 된 문자열을 대문자 혹은 소문자로 변경해줌

- int 함수는 주어진 데이터를 정수형으로 만들어준다
- 실수형 데이터가 주어지면 dot(.)이하의 데이터들은 모두 제거
