AWK 언어를 사용하여 Linux에서 텍스트를 조작하는 방법
소개
Linux 유틸리티는 종종 Unix 설계 철학을 따릅니다. 도구는 작고, 입력 및 출력에 일반 텍스트 파일을 사용하고, 모듈 방식으로 작동하는 것이 좋습니다. 이 레거시 덕분에 우리는 sed 및 awk
와 같은 도구를 사용하여 훌륭한 텍스트 처리 기능을 갖게 되었습니다.
awk
는 매우 유용한 방식으로 텍스트 데이터를 조작하는 데 사용할 수 있는 프로그래밍 언어이자 텍스트 프로세서입니다. 이 가이드에서는 awk
명령줄 도구를 사용하는 방법과 이를 사용하여 텍스트를 처리하는 방법을 살펴봅니다.
기본 구문
awk
명령은 모든 최신 Linux 시스템에 기본적으로 포함되어 있으므로 사용을 시작하기 위해 설치할 필요가 없습니다.
awk
는 예측 가능한 형식의 텍스트 파일을 처리할 때 가장 유용합니다. 예를 들어 테이블 형식 데이터를 구문 분석하고 조작하는 데 탁월합니다. 라인별로 작동하며 전체 파일을 반복합니다.
기본적으로 공백(공백, 탭 등)을 사용하여 필드를 구분합니다. 운 좋게도 Linux 시스템의 많은 구성 파일이 이 형식을 사용합니다.
awk
명령의 기본 형식은 다음과 같습니다.
- awk '/search_pattern/ { action_to_take_on_matches; another_action; }' file_to_parse
awk
명령에서 검색 부분이나 작업 부분을 생략할 수 있습니다. 기본적으로 "action\ 부분이 지정되지 않은 경우 수행되는 작업은 "print\입니다. 이것은 단순히 일치하는 모든 줄을 인쇄합니다.
검색 부분이 지정되지 않은 경우 awk
는 각 줄에 나열된 작업을 수행합니다.
둘 다 제공되면 awk
는 검색 부분을 사용하여 현재 줄이 패턴을 반영하는지 결정한 다음 일치하는 작업을 수행합니다.
가장 간단한 형태로 cat
과 같은 awk
를 사용하여 텍스트 파일의 모든 줄을 화면에 출력할 수 있습니다.
친구 그룹이 좋아하는 음식을 나열하는 favorite_food.txt
파일을 만듭니다.
- echo "carrot sandy
- wasabi luke
- sandwich brian
- salad ryan
- spaghetti jessica" > favorite_food.txt
이제 awk
명령을 사용하여 파일을 화면에 인쇄합니다.
- awk '{print}' favorite_food.txt
파일이 화면에 인쇄된 것을 볼 수 있습니다.
Outputcarrot sandy
wasabi luke
sandwich brian
salad ryan
spaghetti jessica
별로 유용하지 않습니다. 파일에서 "sand\라는 텍스트를 검색하여 awk
의 검색 필터링 기능을 사용해 봅시다.
- awk '/sand/' favorite_food.txt
Outputcarrot sandy
sandwich brian
보시다시피 awk
는 이제 "sand\라는 문자가 있는 줄만 인쇄합니다.
정규식을 사용하면 텍스트의 특정 부분을 대상으로 지정할 수 있습니다. "sand\ 문자로 시작하는 줄만 표시하려면 ^sand
정규식을 사용하세요.
- awk '/^sand/' favorite_food.txt
이번에는 한 줄만 표시됩니다.
Outputsandwich brian
마찬가지로 작업 섹션을 사용하여 인쇄할 정보를 지정할 수 있습니다. 예를 들어 첫 번째 열만 인쇄하려면 다음 명령을 사용하십시오.
- awk '/^sand/ {print $1;}' favorite_food.txt
Outputsandwich
열 번호와 관련된 변수로 모든 열(공백으로 구분됨)을 참조할 수 있습니다. 예를 들어 첫 번째 열은 $1
이고 두 번째 열은 $2
이며 $0
로 전체 줄을 참조할 수 있습니다.
내부 변수 및 확장 형식
awk
명령은 일부 내부 변수를 사용하여 파일을 처리할 때 특정 정보를 할당합니다.
awk
가 사용하는 내부 변수는 다음과 같습니다.
- FILENAME: 현재 입력 파일을 참조합니다.
- FNR: 현재 입력 파일에 상대적인 현재 레코드의 번호를 참조합니다. 예를 들어 두 개의 입력 파일이 있는 경우 전체가 아닌 각 파일의 레코드 번호를 알려줍니다.
- FS: 레코드의 각 필드를 나타내는 데 사용되는 현재 필드 구분 기호입니다. 기본적으로 이것은 공백으로 설정됩니다.
- NF: 현재 레코드의 필드 수.
- NR: 현재 레코드의 번호입니다.
- OFS: 출력 데이터의 필드 구분 기호입니다. 기본적으로 이것은 공백으로 설정됩니다.
- ORS: 출력 데이터의 레코드 구분 기호입니다. 기본적으로 이것은 개행 문자입니다.
- RS: 입력 파일에서 별도의 레코드를 구분하는 데 사용되는 레코드 구분 기호입니다. 기본적으로 이것은 개행 문자입니다.
파일의 요구 사항에 맞게 이러한 변수의 값을 마음대로 변경할 수 있습니다. 일반적으로 처리의 초기화 단계에서 이 작업을 수행합니다.
이것은 우리에게 또 다른 중요한 개념을 제공합니다. awk
구문은 지금까지 사용한 것보다 약간 더 복잡합니다. 실행할 명령을 포함할 수 있는 선택적 BEGIN
및 END
블록도 있습니다. 파일 처리 전과 후.
이렇게 하면 확장된 구문이 다음과 같이 보입니다.
- awk 'BEGIN { action; }
- /search/ { action; }
- END { action; }' input_file
BEGIN
및 END
키워드는 검색 매개변수와 마찬가지로 특정 조건 집합입니다. 문서가 처리되기 전과 후에 일치합니다.
이는 BEGIN
섹션에서 일부 내부 변수를 변경할 수 있음을 의미합니다. 예를 들어 /etc/passwd
파일은 공백 대신 콜론(:
)으로 구분됩니다.
이 파일의 첫 번째 열을 인쇄하려면 다음 명령을 실행하십시오.
- awk 'BEGIN { FS=":"; }
- { print $1; }' /etc/passwd
Outputroot
daemon
bin
sys
sync
games
man
. . .
BEGIN
및 END
블록을 사용하여 인쇄 중인 필드에 대한 정보를 인쇄할 수 있습니다. 다음 명령을 사용하여 파일의 데이터를 테이블로 변환하고
를 사용하여 탭으로 적절한 간격을 두십시오.
- awk 'BEGIN { FS=":"; print "User\t\tUID\t\tGID\t\tHome\t\tShell\n--------------"; }
- {print $1,"\t\t",$3,"\t\t",$4,"\t\t",$6,"\t\t",$7;}
- END { print "---------\nFile Complete" }' /etc/passwd
다음 출력이 표시됩니다.
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
의 일부 기능을 활용하여 매우 멋지게 형식을 지정할 수 있습니다.
확장된 각 섹션은 선택 사항입니다. 실제로 다른 섹션이 정의된 경우 기본 작업 섹션 자체는 선택 사항입니다. 예를 들어 다음과 같이 할 수 있습니다.
- awk 'BEGIN { print "We can use awk like the echo command"; }'
그러면 다음과 같은 출력이 표시됩니다.
OutputWe can use awk like the echo command
이제 출력 필드 내에서 텍스트를 찾는 방법을 살펴보겠습니다.
필드 검색 및 복합 표현식
이전 예 중 하나에서 "sand\로 시작하는 favorite_food.txt
파일의 줄을 인쇄했습니다. 전체 줄의 시작 부분을 찾고 있었기 때문에 이것은 쉬웠습니다.
대신 필드의 시작 부분에서 검색 패턴이 일치하는지 확인하려면 어떻게 해야 합니까?
각 사람의 음식 앞에 항목 번호를 추가하는 favorite_food.txt
파일의 새 버전을 만듭니다.
- echo "1 carrot sandy
- 2 wasabi luke
- 3 sandwich brian
- 4 salad ryan
- 5 spaghetti jessica" > favorite_food.txt
이 파일에서 "sa\로 시작하는 모든 음식을 찾으려면 다음과 같이 시도할 수 있습니다.
- awk '/sa/' favorite_food.txt
다음은 "sa\를 포함하는 모든 줄을 보여줍니다.
Output1 carrot sandy
2 wasabi luke
3 sandwich brian
4 salad ryan
여기에서 단어의 모든 "sa\ 인스턴스를 일치시킵니다. 이것은 중간에 패턴이 있는 "wasabi\ 또는 원하는 열에 없는 "sandy\와 같은 것을 포함하게 됩니다. 여기에서 두 번째 열에 \sa가 있는 시작 단어에만 관심이 있는 경우입니다.
다음 명령을 사용하여 두 번째 열의 시작 부분에서만 일치하도록 awk
에 지시할 수 있습니다.
- awk '$2 ~ /^sa/' favorite_food.txt
보시다시피 이렇게 하면 두 번째 열의 시작 부분에서만 일치 항목을 검색할 수 있습니다.
field_num ~
부분은 awk
가 두 번째 열에만 주의를 기울여야 함을 지정합니다.
Output3 sandwich brian
4 salad ryan
"!”를 포함하여 일치하지 않는 항목을 쉽게 검색할 수 있습니다. 물결표(~) 앞의 문자. 이 명령은 "sa”로 시작하는 음식이 없는 모든 줄을 반환합니다.
- awk '$2 !~ /^sa/' favorite_food.txt
Output1 carrot sandy
2 wasabi luke
5 spaghetti jessica
나중에 "sa\로 시작하지 않고 항목 번호가 5보다 작은 행에만 관심이 있다고 결정하면 다음과 같은 복합 표현식을 사용할 수 있습니다.
- awk '$2 !~ /^sa/ && $1 < 5' favorite_food.txt
이것은 몇 가지 새로운 개념을 소개합니다. 첫 번째는 &&
연산자를 사용하여 일치시킬 라인에 대한 추가 요구 사항을 추가하는 기능입니다. 이를 사용하여 라인이 일치하도록 임의의 수의 조건을 결합할 수 있습니다. 이 경우 이 연산자를 사용하여 첫 번째 열의 값이 5보다 작은지 확인합니다.
다음 출력이 표시됩니다.
Output1 carrot sandy
2 wasabi luke
awk
를 사용하여 파일을 처리할 수 있지만 다른 프로그램의 출력으로 작업할 수도 있습니다.
다른 프로그램의 출력 처리
파일 이름을 지정하는 대신 awk
명령을 사용하여 다른 프로그램의 출력을 구문 분석할 수 있습니다. 예를 들어 awk
를 사용하여 ip
명령에서 IPv4 주소를 구문 분석할 수 있습니다.
ip a
명령은 IP 주소, 브로드캐스트 주소 및 시스템의 모든 네트워크 인터페이스에 대한 기타 정보를 표시합니다. eth0
라는 인터페이스에 대한 정보를 표시하려면 다음 명령을 사용하십시오.
- ip a s 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 주소만 출력할 수 있습니다.
- ip a s eth0 | awk -F '[\/ ]+' '/inet / {print $3}'
-F
플래그는 [\\/ ]+
정규식을 사용하여 슬래시 또는 공백으로 구분하도록 awk
에 지시합니다. 이렇게 하면 inet 172.17.0.11/16
행이 별도의 필드로 분할됩니다. 줄 시작 부분의 공백도 공백과 슬래시로 구분되므로 필드로 계산되기 때문에 IP 주소는 세 번째 필드에 있습니다. 이 경우 awk
는 연속된 공백을 단일 공백으로 처리했습니다.
출력에 IP 주소가 표시됩니다.
Output172.17.0.11
awk
를 사용하여 다른 명령의 출력을 검색하거나 구문 분석할 수 있는 많은 위치를 찾을 수 있습니다.
결론
지금쯤이면 awk
명령을 사용하여 텍스트 파일과 텍스트 스트림을 조작, 서식 지정 및 선택적으로 인쇄하는 방법에 대한 기본적인 이해가 있어야 합니다. 그러나 Awk는 훨씬 더 큰 주제이며 실제로 변수 할당, 제어 구조, 내장 함수 등을 갖춘 전체 프로그래밍 언어입니다. 자신의 스크립트 내에서 이를 사용하여 신뢰할 수 있는 방식으로 텍스트 서식을 지정할 수 있습니다.
awk
에 대해 자세히 알아보려면 작성자가 제공하는 무료 공개 도메인 서적에서 훨씬 더 자세히 알아볼 수 있습니다.