델리미터(Delimeter)로 컬럼이 분기된 텍스트 파일(보통은 아마도 로그파일)을 다룰 때 가장 손쉽게 쓸 수 있는 도구가 awk 입니다. 물론 cut 등도 있지만 탐색한 이후의 작업을 주로 담당하기 때문에 탐색시에는 역시 awk 가 대세입니다. (당연하겠습니다만 awk 도 정규표현식의 탐색을 지원하니 자세한 내용은 글 맨 아래의 포스팅 링크를 참고해 주세요.)
awk 에서 특정 컬럼의 값을 표현하는 방법은 여러가지가 있습니다. 그동안 많이 사용했던 패턴은 아래와 같은 방식이었는데요 이 방식에서도 or, and 조건을 사용하는 것은 문제가 없습니다. 조건을 동시에 만족하는 경우를 찾으려면 &&를, 어느 하나라도 만족하는 경우를 찾으려면 || 를 사용하면 됩니다.
// AND (&&)
awk '$2=="" && $19~/my/ {print $11, $24}'
// OR (||)
awk '$2=="" || $19~/my/ {print $11, $24}'
이렇게 표현하는 방법 외에 브레이스({}) 안쪽에 if 문을 넣어서 사용하는 방법도 있습니다. 어느 방법을 사용하던 원하는 결과를 얻을 수 있으면 되니 손에 더 감기는 방법을 사용하면 좋을 것 같습니다. NOT 조건을 사용하는 경우에도 보다 쉽고 명시적으로 읽을 수 있어서 이 방법을 개인적으로는 선호하는 편입니다.
// AND (&&)
awk '{ if ($5=="/test" && $3=="GET") print $0}'
// OR (&&)
awk '{ if ($5=="/test" || $5=="/beta") print $0}'
// NOT (!)
awk '{ if (!($5=="/test")) print $0}'
쉘에서 로그와 같은 텍스트 파일을 다룰때 정규표현식을 자주 사용하게 됩니다. 정규표현식을 지원하는 쉘의 도구들은 여러가지가 있는데요 오늘은 awk 에서 정규표현식을 사용하는 방법을 간단하게 살펴보겠습니다.
// 일반적인 awk 의 사용 : 첫번째 컬럼 값이 server 인 경우 행($0)을 그대로 출력
$ cat my.log | awk '$1="server" { print $0 }'
// 정규표현식을 만족하는 행 찾기 (Positive Match) : /beta/
$ cat my.log | awk '/\/beta\// { print $0 }'
// 정규표현식을 만족하지 않는 행 찾기 (Negative Match) : /beta/ 가 아닌 경우
$ cat my.log | awk '!/\/beta\// { print $0 }'
일반적으로 awk 는 독립적으로 사용되지 않고 cat 과 같은 다른 명령과 파이프(|)로 연결해서 문자열을 다룹니다. 위 코드의 첫번째 예시는 awk 가 델리미터 단위로 행을 분할해주는 기능을 이용하여 첫번째 컬럼($1)의 값이 만족하는 경우 해당 행을 출력하는 명령입니다.
정규표현식을 이용하려면 슬래시로 정규 표현식 문자열을 넣어주면 됩니다. 가령 URL 에 /beta/ 라는 path 가 존재할 수 있고, 해당 항목이 있는 경우만 출력한다면 \/beta\/ 로 표현식을 만들면 됩니다. 두번째 예시를 참고하시면 되겠습니다.
정규표현식을 만족하지 않는 Negative Match 로 자료를 찾아야 하는 경우도 있습니다. 이때는 정규 표현식을 감싸고 있는 슬래시의 앞에 느낌표(!)를 붙여주기만 하면 됩니다.