웹사이트 검색

AWK 언어를 사용하여 Linux에서 텍스트를 조작하는 방법


소개

Linux 유틸리티는 종종 Unix 설계 철학을 따릅니다. 도구는 작고, 입력 및 출력에 일반 텍스트 파일을 사용하고, 모듈 방식으로 작동하는 것이 좋습니다. 이 레거시 덕분에 우리는 sed 및 awk와 같은 도구를 사용하여 훌륭한 텍스트 처리 기능을 갖게 되었습니다.

awk는 매우 유용한 방식으로 텍스트 데이터를 조작하는 데 사용할 수 있는 프로그래밍 언어이자 텍스트 프로세서입니다. 이 가이드에서는 awk 명령줄 도구를 사용하는 방법과 이를 사용하여 텍스트를 처리하는 방법을 살펴봅니다.

기본 구문

awk 명령은 모든 최신 Linux 시스템에 기본적으로 포함되어 있으므로 사용을 시작하기 위해 설치할 필요가 없습니다.

awk는 예측 가능한 형식의 텍스트 파일을 처리할 때 가장 유용합니다. 예를 들어 테이블 형식 데이터를 구문 분석하고 조작하는 데 탁월합니다. 라인별로 작동하며 전체 파일을 반복합니다.

기본적으로 공백(공백, 탭 등)을 사용하여 필드를 구분합니다. 운 좋게도 Linux 시스템의 많은 구성 파일이 이 형식을 사용합니다.

awk 명령의 기본 형식은 다음과 같습니다.

  1. awk '/search_pattern/ { action_to_take_on_matches; another_action; }' file_to_parse

awk 명령에서 검색 부분이나 작업 부분을 생략할 수 있습니다. 기본적으로 "action\ 부분이 지정되지 않은 경우 수행되는 작업은 "print\입니다. 이것은 단순히 일치하는 모든 줄을 인쇄합니다.

검색 부분이 지정되지 않은 경우 awk는 각 줄에 나열된 작업을 수행합니다.

둘 다 제공되면 awk는 검색 부분을 사용하여 현재 줄이 패턴을 반영하는지 결정한 다음 일치하는 작업을 수행합니다.

가장 간단한 형태로 cat과 같은 awk를 사용하여 텍스트 파일의 모든 줄을 화면에 출력할 수 있습니다.

친구 그룹이 좋아하는 음식을 나열하는 favorite_food.txt 파일을 만듭니다.

  1. echo "carrot sandy
  2. wasabi luke
  3. sandwich brian
  4. salad ryan
  5. spaghetti jessica" > favorite_food.txt

이제 awk 명령을 사용하여 파일을 화면에 인쇄합니다.

  1. awk '{print}' favorite_food.txt

파일이 화면에 인쇄된 것을 볼 수 있습니다.

Output
carrot sandy wasabi luke sandwich brian salad ryan spaghetti jessica

별로 유용하지 않습니다. 파일에서 "sand\라는 텍스트를 검색하여 awk의 검색 필터링 기능을 사용해 봅시다.

  1. awk '/sand/' favorite_food.txt
Output
carrot sandy sandwich brian

보시다시피 awk는 이제 "sand\라는 문자가 있는 줄만 인쇄합니다.

정규식을 사용하면 텍스트의 특정 부분을 대상으로 지정할 수 있습니다. "sand\ 문자로 시작하는 줄만 표시하려면 ^sand 정규식을 사용하세요.

  1. awk '/^sand/' favorite_food.txt

이번에는 한 줄만 표시됩니다.

Output
sandwich brian

마찬가지로 작업 섹션을 사용하여 인쇄할 정보를 지정할 수 있습니다. 예를 들어 첫 번째 열만 인쇄하려면 다음 명령을 사용하십시오.

  1. awk '/^sand/ {print $1;}' favorite_food.txt
Output
sandwich

열 번호와 관련된 변수로 모든 열(공백으로 구분됨)을 참조할 수 있습니다. 예를 들어 첫 번째 열은 $1이고 두 번째 열은 $2이며 $0로 전체 줄을 참조할 수 있습니다.

내부 변수 및 확장 형식

awk 명령은 일부 내부 변수를 사용하여 파일을 처리할 때 특정 정보를 할당합니다.

awk가 사용하는 내부 변수는 다음과 같습니다.

  • FILENAME: 현재 입력 파일을 참조합니다.
  • FNR: 현재 입력 파일에 상대적인 현재 레코드의 번호를 참조합니다. 예를 들어 두 개의 입력 파일이 있는 경우 전체가 아닌 각 파일의 레코드 번호를 알려줍니다.
  • FS: 레코드의 각 필드를 나타내는 데 사용되는 현재 필드 구분 기호입니다. 기본적으로 이것은 공백으로 설정됩니다.
  • NF: 현재 레코드의 필드 수.
  • NR: 현재 레코드의 번호입니다.
  • OFS: 출력 데이터의 필드 구분 기호입니다. 기본적으로 이것은 공백으로 설정됩니다.
  • ORS: 출력 데이터의 레코드 구분 기호입니다. 기본적으로 이것은 개행 문자입니다.
  • RS: 입력 파일에서 별도의 레코드를 구분하는 데 사용되는 레코드 구분 기호입니다. 기본적으로 이것은 개행 문자입니다.

파일의 요구 사항에 맞게 이러한 변수의 값을 마음대로 변경할 수 있습니다. 일반적으로 처리의 초기화 단계에서 이 작업을 수행합니다.

이것은 우리에게 또 다른 중요한 개념을 제공합니다. awk 구문은 지금까지 사용한 것보다 약간 더 복잡합니다. 실행할 명령을 포함할 수 있는 선택적 BEGINEND 블록도 있습니다. 파일 처리 전과 후.

이렇게 하면 확장된 구문이 다음과 같이 보입니다.

  1. awk 'BEGIN { action; }
  2. /search/ { action; }
  3. END { action; }' input_file

BEGINEND 키워드는 검색 매개변수와 마찬가지로 특정 조건 집합입니다. 문서가 처리되기 전과 후에 일치합니다.

이는 BEGIN 섹션에서 일부 내부 변수를 변경할 수 있음을 의미합니다. 예를 들어 /etc/passwd 파일은 공백 대신 콜론(:)으로 구분됩니다.

이 파일의 첫 번째 열을 인쇄하려면 다음 명령을 실행하십시오.

  1. awk 'BEGIN { FS=":"; }
  2. { print $1; }' /etc/passwd
Output
root daemon bin sys sync games man . . .

BEGINEND 블록을 사용하여 인쇄 중인 필드에 대한 정보를 인쇄할 수 있습니다. 다음 명령을 사용하여 파일의 데이터를 테이블로 변환하고 를 사용하여 탭으로 적절한 간격을 두십시오.

  1. awk 'BEGIN { FS=":"; print "User\t\tUID\t\tGID\t\tHome\t\tShell\n--------------"; }
  2. {print $1,"\t\t",$3,"\t\t",$4,"\t\t",$6,"\t\t",$7;}
  3. END { print "---------\nFile Complete" }' /etc/passwd

다음 출력이 표시됩니다.

Output
User 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의 일부 기능을 활용하여 매우 멋지게 형식을 지정할 수 있습니다.

확장된 각 섹션은 선택 사항입니다. 실제로 다른 섹션이 정의된 경우 기본 작업 섹션 자체는 선택 사항입니다. 예를 들어 다음과 같이 할 수 있습니다.

  1. awk 'BEGIN { print "We can use awk like the echo command"; }'

그러면 다음과 같은 출력이 표시됩니다.

Output
We can use awk like the echo command

이제 출력 필드 내에서 텍스트를 찾는 방법을 살펴보겠습니다.

필드 검색 및 복합 표현식

이전 예 중 하나에서 "sand\로 시작하는 favorite_food.txt 파일의 줄을 인쇄했습니다. 전체 줄의 시작 부분을 찾고 있었기 때문에 이것은 쉬웠습니다.

대신 필드의 시작 부분에서 검색 패턴이 일치하는지 확인하려면 어떻게 해야 합니까?

각 사람의 음식 앞에 항목 번호를 추가하는 favorite_food.txt 파일의 새 버전을 만듭니다.

  1. echo "1 carrot sandy
  2. 2 wasabi luke
  3. 3 sandwich brian
  4. 4 salad ryan
  5. 5 spaghetti jessica" > favorite_food.txt

이 파일에서 "sa\로 시작하는 모든 음식을 찾으려면 다음과 같이 시도할 수 있습니다.

  1. awk '/sa/' favorite_food.txt

다음은 "sa\를 포함하는 모든 줄을 보여줍니다.

Output
1 carrot sandy 2 wasabi luke 3 sandwich brian 4 salad ryan

여기에서 단어의 모든 "sa\ 인스턴스를 일치시킵니다. 이것은 중간에 패턴이 있는 "wasabi\ 또는 원하는 열에 없는 "sandy\와 같은 것을 포함하게 됩니다. 여기에서 두 번째 열에 \sa가 있는 시작 단어에만 관심이 있는 경우입니다.

다음 명령을 사용하여 두 번째 열의 시작 부분에서만 일치하도록 awk에 지시할 수 있습니다.

  1. awk '$2 ~ /^sa/' favorite_food.txt

보시다시피 이렇게 하면 두 번째 열의 시작 부분에서만 일치 항목을 검색할 수 있습니다.

field_num ~ 부분은 awk가 두 번째 열에만 주의를 기울여야 함을 지정합니다.

Output
3 sandwich brian 4 salad ryan

"!”를 포함하여 일치하지 않는 항목을 쉽게 검색할 수 있습니다. 물결표(~) 앞의 문자. 이 명령은 "sa”로 시작하는 음식이 없는 모든 줄을 반환합니다.

  1. awk '$2 !~ /^sa/' favorite_food.txt
Output
1 carrot sandy 2 wasabi luke 5 spaghetti jessica

나중에 "sa\로 시작하지 않고 항목 번호가 5보다 작은 행에만 관심이 있다고 결정하면 다음과 같은 복합 표현식을 사용할 수 있습니다.

  1. awk '$2 !~ /^sa/ && $1 < 5' favorite_food.txt

이것은 몇 가지 새로운 개념을 소개합니다. 첫 번째는 && 연산자를 사용하여 일치시킬 라인에 대한 추가 요구 사항을 추가하는 기능입니다. 이를 사용하여 라인이 일치하도록 임의의 수의 조건을 결합할 수 있습니다. 이 경우 이 연산자를 사용하여 첫 번째 열의 값이 5보다 작은지 확인합니다.

다음 출력이 표시됩니다.

Output
1 carrot sandy 2 wasabi luke

awk를 사용하여 파일을 처리할 수 있지만 다른 프로그램의 출력으로 작업할 수도 있습니다.

다른 프로그램의 출력 처리

파일 이름을 지정하는 대신 awk 명령을 사용하여 다른 프로그램의 출력을 구문 분석할 수 있습니다. 예를 들어 awk를 사용하여 ip 명령에서 IPv4 주소를 구문 분석할 수 있습니다.

ip a 명령은 IP 주소, 브로드캐스트 주소 및 시스템의 모든 네트워크 인터페이스에 대한 기타 정보를 표시합니다. eth0라는 인터페이스에 대한 정보를 표시하려면 다음 명령을 사용하십시오.

  1. ip a s eth0

다음과 같은 결과가 표시됩니다.

Output
2571: 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 주소만 출력할 수 있습니다.

  1. ip a s eth0 | awk -F '[\/ ]+' '/inet / {print $3}'

-F 플래그는 [\\/ ]+ 정규식을 사용하여 슬래시 또는 공백으로 구분하도록 awk에 지시합니다. 이렇게 하면 inet 172.17.0.11/16 행이 별도의 필드로 분할됩니다. 줄 시작 부분의 공백도 공백과 슬래시로 구분되므로 필드로 계산되기 때문에 IP 주소는 세 번째 필드에 있습니다. 이 경우 awk는 연속된 공백을 단일 공백으로 처리했습니다.

출력에 IP 주소가 표시됩니다.

Output
172.17.0.11

awk를 사용하여 다른 명령의 출력을 검색하거나 구문 분석할 수 있는 많은 위치를 찾을 수 있습니다.

결론

지금쯤이면 awk 명령을 사용하여 텍스트 파일과 텍스트 스트림을 조작, 서식 지정 및 선택적으로 인쇄하는 방법에 대한 기본적인 이해가 있어야 합니다. 그러나 Awk는 훨씬 더 큰 주제이며 실제로 변수 할당, 제어 구조, 내장 함수 등을 갖춘 전체 프로그래밍 언어입니다. 자신의 스크립트 내에서 이를 사용하여 신뢰할 수 있는 방식으로 텍스트 서식을 지정할 수 있습니다.

awk에 대해 자세히 알아보려면 작성자가 제공하는 무료 공개 도메인 서적에서 훨씬 더 자세히 알아볼 수 있습니다.