소개
리눅스 유틸리티는 종종 Unix 설계 철학을 따릅니다. 도구들은 작고 입력 및 출력으로 평범한 텍스트 파일을 사용하고 모듈식으로 작동하도록 장려됩니다. 이러한 유산으로 인해, 우리는 sed 및 awk
와 같은 도구를 사용하여 훌륭한 텍스트 처리 기능을 갖추고 있습니다.
awk
는 텍스트 데이터를 매우 유용한 방식으로 조작하는 데 사용할 수 있는 프로그래밍 언어 및 텍스트 프로세서입니다. 이 가이드에서는 awk
명령 줄 도구를 사용하는 방법과 텍스트를 처리하는 방법을 살펴보겠습니다.
기본 구문
awk
명령은 모든 현대 리눅스 시스템에 기본적으로 포함되어 있으므로 사용을 시작하려면 설치할 필요가 없습니다.
awk
는 예측 가능한 방식으로 서식이 지정된 텍스트 파일을 처리할 때 가장 유용합니다. 예를 들어, 테이블 형식의 데이터를 구문 분석하고 조작하는 데 우수합니다. 파일을 한 줄씩 처리하며 전체 파일을 반복합니다.
기본적으로 공백(공백, 탭 등)을 필드로 분리합니다. 다행히도 리눅스 시스템의 많은 구성 파일이 이 형식을 사용합니다.
awk
명령어의 기본 형식은 다음과 같습니다:
검색 부분 또는 동작 부분 중 하나를 생략할 수 있습니다. 기본적으로 “동작” 부분이 지정되지 않은 경우 취해지는 동작은 “출력”입니다. 이는 단순히 일치하는 모든 줄을 출력합니다.
검색 부분이 지정되지 않은 경우 awk
는 각 줄에 나열된 동작을 수행합니다.
둘 다 지정된 경우 awk
는 현재 줄이 패턴을 반영하는지 여부를 결정하기 위해 검색 부분을 사용하고 일치하는 경우 동작을 수행합니다.
가장 간단한 형태에서는 awk
를 cat
처럼 사용하여 텍스트 파일의 모든 줄을 화면에 출력할 수 있습니다.
일련의 친구들의 좋아하는 음식을 나열하는 favorite_food.txt
파일을 생성하세요:
이제 awk
명령어를 사용하여 파일을 화면에 출력하세요:
파일이 화면에 출력됩니다:
Outputcarrot sandy
wasabi luke
sandwich brian
salad ryan
spaghetti jessica
이것은 그다지 유용하지 않습니다. 파일에서 텍스트 “sand”를 검색하여 awk
의 검색 필터링 기능을 시도해 보겠습니다:
Outputcarrot sandy
sandwich brian
awk
는 이제 “sand” 문자를 포함하는 줄만 출력합니다.
정규 표현식을 사용하여 텍스트의 특정 부분을 대상으로 할 수 있습니다. “sand”로 시작하는 줄만 표시하려면 다음 정규 표현식을 사용하십시오: ^sand
:
이번에는 한 줄만 표시됩니다:
Outputsandwich brian
마찬가지로, 동작 부분을 사용하여 인쇄할 정보의 일부를 지정할 수 있습니다. 예를 들어, 첫 번째 열만 인쇄하려면 다음 명령어를 사용하십시오:
Outputsandwich
모든 열을 변수와 연결된 열 번호로 참조할 수 있습니다. 예를 들어, 첫 번째 열은 $1
, 두 번째는 $2
이며, 전체 줄은 $0
으로 참조할 수 있습니다.
내부 변수 및 확장된 형식
awk
명령은 파일을 처리하는 동안 특정 정보를 할당하기 위해 일부 내부 변수를 사용합니다.
awk
가 사용하는 내부 변수는 다음과 같습니다:
- FILENAME: 현재 입력 파일을 참조합니다.
- FNR: 현재 입력 파일에 대한 현재 레코드 번호를 참조합니다. 예를 들어, 두 개의 입력 파일이 있는 경우 각 파일의 레코드 번호를 총계가 아닌 파일별로 알려줍니다.
- FS: 레코드의 각 필드를 나타내는 현재 필드 구분자입니다. 기본적으로 공백으로 설정됩니다.
- NF: 현재 레코드의 필드 수입니다.
- NR: 현재 레코드의 번호입니다.
- OFS: 출력된 데이터의 필드 구분자입니다. 기본적으로 공백으로 설정됩니다.
- ORS: 출력된 데이터의 레코드 구분자입니다. 기본적으로 개행 문자입니다.
- RS: 입력 파일에서 별도의 레코드를 구별하는 데 사용되는 레코드 구분자입니다. 기본적으로 이는 새 줄 문자입니다.
이러한 변수의 값을 파일의 필요에 맞게 자유롭게 변경할 수 있습니다. 일반적으로 이것은 처리의 초기화 단계 중에 수행됩니다.
이것은 또 다른 중요한 개념으로 이어집니다. awk
구문은 여태까지 사용한 것보다 약간 더 복잡합니다. 선택적으로 BEGIN
및 END
블록도 있으며 각각 파일 처리 전후에 실행할 명령을 포함할 수 있습니다.
이로써 우리의 확장된 구문은 다음과 같이 보입니다:
BEGIN
및 END
키워드는 검색 매개변수와 마찬가지로 특정한 조건 세트입니다. 이들은 문서가 처리된 전후에 일치합니다.
즉, BEGIN
섹션에서 일부 내부 변수를 변경할 수 있습니다. 예를 들어, /etc/passwd
파일은 공백 대신 콜론(:
)으로 구분됩니다.
이 파일의 첫 번째 열을 출력하려면 다음 명령을 실행하세요:
Outputroot
daemon
bin
sys
sync
games
man
. . .
BEGIN
및 END
블록을 사용하여 인쇄 중인 필드에 대한 정보를 인쇄할 수 있습니다. 다음 명령을 사용하여 파일에서 데이터를 테이블로 변환하고 탭으로 아름답게 공간을 만듭니다:
다음 출력이 표시됩니다:
OutputUser UID GID Home Shell
--------------
root 0 0 /root /bin/bash
daemon 1 1 /usr/sbin /bin/sh
bin 2 2 /bin /bin/sh
sys 3 3 /dev /bin/sh
sync 4 65534 /bin /bin/sync
. . .
---------
File Complete
보시다시피, awk
의 기능을 활용하여 출력을 꽤 멋지게 포맷할 수 있습니다.
확장된 섹션들 중 각각은 선택 사항입니다. 사실, 다른 섹션을 정의한 경우에는 주요 작업 섹션이 선택 사항입니다. 예를 들어, 이렇게 할 수 있습니다:
그리고 이 출력을 볼 수 있습니다:
OutputWe can use awk like the echo command
이제 출력의 필드 내에서 텍스트를 찾는 방법을 살펴 보겠습니다.
필드 검색 및 복합 표현식
이전 예제 중 하나에서는 “sand”로 시작하는 favorite_food.txt
파일의 줄을 출력했습니다. 전체 줄의 시작을 찾았기 때문에 이것은 쉬웠습니다.
그런데 만약 검색 패턴이 필드의 시작 부분과 일치하는지 알고 싶다면 어떨까요?
각 사람의 음식 앞에 항목 번호를 추가한 favorite_food.txt
파일의 새 버전을 만듭니다:
이 파일에서 “sa”로 시작하는 모든 음식을 찾으려면 다음과 같은 작업을 시도해 볼 수 있습니다:
이렇게 하면 “sa”가 포함된 모든 줄이 표시됩니다:
Output1 carrot sandy
2 wasabi luke
3 sandwich brian
4 salad ryan
여기서 단어의 어느 부분에서든 “sa”에 일치시킵니다. 이는 “wasabi”와 같은 가운데에 패턴이 있는 것이나 원하지 않는 “sandy”와 같은 것을 포함하게 됩니다. 이 경우에는 두 번째 열에서 “sa”로 시작하는 단어에만 관심이 있습니다. 시작하는 “sa”로만 두 번째 열에 있는 단어입니다.
당신은 이 명령어를 사용하여 awk
에게 두 번째 열의 시작 부분에만 일치하도록 지시할 수 있습니다:
이렇게 하면 일치 항목을 찾을 때 두 번째 열의 시작 부분에서만 검색할 수 있습니다.
field_num ~
부분은 awk
가 두 번째 열에만 주의를 기울여야 함을 지정합니다.
Output3 sandwich brian
4 salad ryan
동일하게 “!” 문자를 물결(~) 문자 앞에 포함하여 일치하지 않는 항목을 쉽게 검색할 수 있습니다. 이 명령은 “sa”로 시작하는 음식이 없는 모든 줄을 반환합니다:
Output1 carrot sandy
2 wasabi luke
5 spaghetti jessica
“sa”로 시작하지 않고 항목 번호가 5보다 작은 줄에만 관심이 있다고 나중에 결정하면 다음과 같이 복합 표현식을 사용할 수 있습니다:
여기에는 몇 가지 새로운 개념이 소개됩니다. 첫 번째는 &&
연산자를 사용하여 일치하는 줄에 대한 추가 요구 사항을 추가할 수 있는 능력입니다. 이를 사용하면 줄이 일치하려면 임의의 수의 조건을 결합할 수 있습니다. 이 경우 첫 번째 열의 값이 5보다 작은지를 확인하는 검사를 추가하기 위해 이 연산자를 사용합니다.
다음 출력이 표시됩니다:
Output1 carrot sandy
2 wasabi luke
awk
를 파일 처리에 사용할 수 있지만 다른 프로그램의 출력물도 처리할 수 있습니다.
다른 프로그램의 출력 처리
다른 프로그램의 출력을 지정된 파일 이름을 사용하는 대신 awk
명령을 사용할 수 있습니다. 예를 들어, ip
명령에서 IPv4 주소를 구문 분석하는 데 awk
를 사용할 수 있습니다.
ip a
명령은 기계에있는 모든 네트워크 인터페이스에 대한 IP 주소, 브로드캐스트 주소 및 기타 정보를 표시합니다. eth0
이라는 인터페이스의 정보를 표시하려면 이 명령을 사용하십시오:
다음과 같은 결과가 표시됩니다:
Output2571: eth0@if2572: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:0b brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.11/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
awk
를 사용하여 inet
줄을 대상으로하고 IP 주소 만 인쇄 할 수 있습니다:
-F
플래그는 정규 표현식 [\/ ]+
을 사용하여 슬래시 또는 공백으로 분리하도록 awk
에 지시합니다. 이렇게하면 라인 inet 172.17.0.11/16
이 개별 필드로 분할됩니다. IP 주소는 세 번째 필드에 있습니다. 라인 시작 부분의 공백도 슬래시뿐만 아니라 슬래시로 분리했기 때문에 필드로 계산됩니다.이 경우 awk
는 연속적인 공백을 단일 공백으로 취급했습니다.
출력에는 IP 주소가 표시됩니다:
Output172.17.0.11
awk
를 사용하여 다른 명령의 출력을 검색하거나 구문 분석 할 수 있는 여러 위치를 찾을 수 있습니다.
결론
지금쯤이면, 텍스트 파일 및 텍스트 스트림을 조작, 형식화 및 선택적으로 출력하는 방법에 awk
명령을 사용할 수 있는 기본적인 이해가 있어야합니다. 그러나 Awk는 실제로 변수 할당, 제어 구조, 내장 함수 등이 포함된 전체 프로그래밍 언어입니다. 신뢰할 수 있는 방식으로 텍스트를 형식화하기 위해 자신의 스크립트 내에서 사용할 수 있습니다.
awk
에 대해 더 알아보려면 그 창조자들에 의한 무료 공용 도메인 도서를 읽어보십시오. 이 책은 훨씬 더 자세히 설명합니다.