>php教程 >PHP开发 >awk 명령에 대한 자세한 설명

awk 명령에 대한 자세한 설명

高洛峰
高洛峰원래의
2016-12-15 11:06:381476검색

1. 서문

Awk에는 awk, nawk 및 gawk의 세 가지 버전이 있습니다. 지정하지 않으면 일반적으로 gawk를 나타냅니다. awk 언어의 가장 기본적인 기능은 지정된 규칙에 따라 파일이나 문자열에서 정보를 분해하고 추출하는 것이며 지정된 규칙에 따라 데이터를 출력할 수도 있습니다. 완전한 awk 스크립트는 일반적으로 텍스트 파일의 정보 형식을 지정하는 데 사용됩니다.

2. 기본 구문

awk [opion] 'awk_script' input_file1 [input_file2 ...]

awk의 일반적인 옵션은 다음과 같습니다.

① -F fs: fs를 입력 레코드의 필드 구분 기호로 사용합니다. 이 옵션을 생략하면 awk는 환경 변수 IFS

의 값을 사용합니다. ② -f filename: awk_script

를 읽습니다. file filename ③ -v var=value: awk_script에 대한 변수 설정

Awk에는 세 가지 실행 모드가 있습니다.

첫 번째는 awk 스크립트 명령을 명령에 직접 넣는 것입니다.

둘째, awk의 모든 스크립트 명령어를 스크립트 파일에 넣은 후 -f 옵션을 사용하여 실행할 스크립트 명령어 파일을 지정합니다.

세 번째 방법은 awk_script를 스크립트 파일에 넣고 첫 번째 줄에 #!/bin/awk -f를 사용하고 스크립트에 실행 권한을 부여한 후 셸에 스크립트 이름을 입력하여 호출하는 것입니다. .

3. Awk 스크립트

Awk 스크립트는 하나 이상의 awk_cmd로 구성될 수 있습니다. 여러 개의 awk_cmd의 경우 하나의 awk_cmd가 완료된 후 분리를 위해 새 줄을 시작해야 합니다.

awk_cmd는 awk_pattern { actions }의 두 부분으로 구성됩니다.

또한 awk 명령에서 awk_script를 직접 사용하는 경우 awk_script를 여러 줄로 작성할 수도 있지만 awk_script 전체를 작은따옴표로 묶어야 합니다.

awk 명령의 일반적인 형식:

awk ' BEGIN { actions }

awk_pattern1 { actions }

........ ..

awk_patternN { actions }

END { actions }

' inputfile

여기서 BEGIN { actions } 및 END { actions } 는 선택 사항입니다.

awk 스크립트에서 다음과 같이 AWK 자체 내장 변수를 사용할 수 있습니다.

ARGC 명령줄 ​​인수 수

ARGV 명령줄 인수 배열

FILENAME 현재 입력 파일 이름

현재 파일의 FNR 레코드 번호

FS 입력 필드 구분 기호, 기본값은 공백입니다

RS 입력 레코드 구분 기호

NF 현재 레코드의 필드 수

NR 지금까지의 레코드 수

OFS 출력 필드 구분 기호

ORS 출력 레코드 구분 기호

awk 스크립트 실행 중인 프로세스:

① BEGIN 블록이 있으면 awk는 해당 블록에 지정된 작업을 실행합니다.

② awk는 입력 레코드라고 하는 입력 파일에서 한 줄을 읽습니다. (입력 파일을 생략하면 표준 입력에서 읽습니다.)

3 awk는 읽은 레코드를 필드로 분할하고 첫 번째 필드를 변수 $1에 두 번째 필드를 $2에 넣는 식으로 에. $0은 전체 레코드를 나타냅니다. 필드 구분 기호는 쉘 환경 변수 IFS를 사용하거나 매개변수로 지정됩니다.

④ 현재 입력된 레코드와 각 awk_cmd의 awk_pattern을 비교하여 일치하는지 확인하고, 일치하면 해당 액션을 실행합니다. 일치하는 항목이 없으면 모든 awk_cmd가 비교될 때까지 해당 작업을 건너뜁니다.

⑤ 입력 레코드가 모든 awk_cmd를 비교하면 awk는 입력의 다음 줄을 읽고 awk가 파일의 끝을 읽을 때까지 계속해서 ③과 ④ 단계를 반복합니다.

⑥ awk가 모든 입력 라인을 읽은 후 END가 존재하면 해당 작업이 실행됩니다.

1) input_file은 두 개 이상의 파일이 포함된 파일 목록일 수 있으며, awk는 목록에 있는 각 파일을 순서대로 처리합니다.

2) awk_cmd의 awk_pattern은 생략 가능하며, 생략 시 입력 레코드와의 매칭 비교 없이 해당 액션이 실행됩니다. awk_cmd 작업을 생략할 수도 있습니다. 생략하면 기본 작업은 현재 입력 레코드, 즉 {print $0}을 인쇄하는 것입니다. awk_pattern과 awk_cmd의 작업은 동시에 생략할 수 없습니다.

3) BEGIN 블록과 END 블록은 각각 awk_script의 시작과 끝 부분에 위치합니다. awk_script에서는 END 블록 또는 BEGIN 블록만 허용됩니다. awk_script에 BEGIN { actions }만 있는 경우 awk는 input_file을 읽지 않습니다.

4) awk는 입력 파일의 데이터를 메모리로 읽은 다음 메모리에 있는 입력 데이터의 복사본을 작업합니다. awk는 입력 파일의 내용을 수정하지 않습니다.

5) awk는 항상 표준 출력으로 출력합니다. awk를 파일로 출력하려면 리디렉션을 사용할 수 있습니다.

3.1.awk_pattern

awk_pattern 패턴 부분은 작업 작업 부분이 작업을 트리거하고 트리거하는 시기를 결정합니다.

awk_pattern은 다음 유형일 수 있습니다.

1) 정규 표현식은 awk_pattern으로 사용됩니다: /regexp/

정규 표현식 regexp는 / 래핑되어야 합니다.

awk의 정규식 일치 작업에 자주 사용되는 문자:

^ $ . [] | () * //: 일반적인 정규 표현식 메타 문자

+: 그 앞의 단일 문자와 일치합니다. awk 자체 메타 문자입니다.

? : awk 자체 메타 문자이며 grep에 적합하지 않습니다. 또는 sed 등

정규식에 대한 자세한 내용은 "정규식"을 참조하세요.

예:

awk '/ *$0. [0-9].*/' input_file

예를 들어 행 내용은 $0.99입니다. helllo 행은 위의 정규 표현식과 일치할 수 있습니다

2) 불리언 표현식 표현식은 awk_pattern으로 사용됩니다. . 표현식이 설정되면 해당 작업이 실행됩니다.

① 변수(예: 필드 변수 $1, $2 등) 및 /regexp/

② 부울 표현식의 연산자를 사용할 수 있습니다.

관계 연산자: < > <= >= == !=

일치 연산자: value ~ /regexp/ 값이 /regexp/와 일치하면 true

값을 반환합니다. !~ /regexp/ 값이 /regexp/와 일치하지 않으면 true를 반환합니다

예: awk '$2 > 10 {print "ok"}' input_file

awk '$3 ~ /^ d/ {print "ok"}' input_file

3 &&(and) 및 ||(or)는 두 개의 /regexp/ 또는 부울 표현식을 연결하여 혼합 표현식을 형성할 수 있습니다. !(not)은 부울 표현식이나 /regexp/ 앞에 사용할 수 있습니다.

예: awk '($1 < 10 ) && ($2 > 10) {print $0 "ok"}' input_file

awk '/^d/ || {print $0 "ok"}' input_file

④ 할당 표현식 등 다른 표현식이 awk_script로 사용됩니다.

예:

awk '(tot+=$6 ); END{print "total points :" tot }' input_file // 세미콜론은 생략할 수 없습니다

awk 'tot+=$6 {print $0} END{print "total points :" tot }' input_file // 동일 위와 같습니다.

할당 표현식을 사용할 때 할당된 변수가 숫자이면 0이 아니면 일치하고, 그렇지 않으면 문자열이면 일치하지 않는다는 의미입니다. 비어 있지 않으면 일치하고, 그렇지 않으면 일치하지 않습니다.


awk 내장 문자열 함수:

gsub(r, s) $0 전체에서 r을 s로 대체

awk 'gsub( /name/, "xingming") {print $0}' temp

gsub(r, s, t) r

index(s, t)를 전체 t에서 s로 대체합니다. s

awk 'BEGIN {print index("Sunny", "ny")}' temp에서 문자열 t의 첫 번째 위치 4를 반환

length(s) s의 길이를 반환

match(s, r) s에 r과 일치하는 문자열이 포함되어 있는지 테스트

awk '$1=="J.Lulu" {print match($1, "u")}' temp Return 4

split(s, a, fs) s를 a

awk 'BEGIN {print Split("12#345#6789", myarray, "#") on fs "' 시퀀스로 나눕니다.

은 3을 반환하고 myarray[1]="12", myarray[2]="345", myarray[3]="6789"

sprint(fmt, exp) 반환 exp

fmt로 형식화된 후의 sub(r, s) r을 $0의 가장 왼쪽에서 가장 긴 하위 문자열의 s로 바꿉니다(첫 번째로 일치하는 문자열만 바꿉니다)

substr(s, p) 반환 문자열 s에서 p로 시작하는 접미사 부분

substr(s, p, n) p에서 시작하고 문자열 s에서 길이가 n인 접미사 부분을 반환합니다

awk 문자열 연결 연산

[chengmo@centos5 ~]$ awk 'BEGIN{a="a";b="b";c=(a""b);print c} '

ab

2.7. printf 함수 사용:

문자 변환: echo "65" |awk '{printf "%cn",$0}' 출력 A

awk 'BEGIN {printf "% fn",999}' 출력 999.000000

형식화된 출력: awk '{printf "%-15s %sn",$1,$3}' temp가 첫 번째가 됩니다. 필드의 모든 필드는 왼쪽 정렬되어 표시됩니다.

2.8. 기타 awk 사용법:

awk 명령 줄에 값 전달:

awk '{if ($5

who | awk ' {if ($1==user) print $1 " are in " $2 ' user=$LOGNAME 환경 변수

awk 스크립트 명령 사용:

시작 부분에 !/bin/awk 사용 - f, 이 문장이 없으면 자체 포함 스크립트는 실행되지 않습니다. 예:

!/bin/awk -f

# 모든 주석 줄은 해시 '#'으로 시작해야 합니다

# 이름: Student_tot.awk

# 전화: Student_tot.awk grade.txt

# 동아리 학생 포인트의 총합과 평균을 인쇄합니다

# a를 인쇄합니다. 헤더 먼저

BEGIN

{

print "학생 날짜 회원 번호 학년 나이 포인트 최대"

인쇄 "가입한 이름 획득 포인트 사용 가능"

인쇄"=========================================== ============="

}

# 획득한 점수를 더해보겠습니다

(tot+=$6);

# 처리가 완료되었으니 이제 총점과 평균점을 출력해 보겠습니다

END

{

print "동아리 학생 총점:" tot

print "평균 동아리 학생 점수:" tot/N

}


2.9. awk 배열:

awk의 기본 루프 구조

For (배열의 요소) print array[element]

awk 'BEGIN {record="123#456#789";split(record, myarray, "#")}

END { for (i in myarray) {print myarray[i]} }

3.0 awk의 사용자 정의문

1. 조건부 판단문(if)


if(표현식) #if(배열의 변수)

문장 1

else

문장 2

"문장 형식의 1"은 여러 문이 될 수 있습니다. Unix의 awk 판단과 자체 읽기를 용이하게 하려면 여러 문을 {}로 묶는 것이 좋습니다. Unix awk 분기 구조는 중첩을 허용하며 형식은 다음과 같습니다.


if(표현식)


{문 1}


else if(표현식)

{문 2}

else

{문 3}

[chengmo@localhost nginx]# awk 'BEGIN {

test=100;

if(test>90)

{

"very good" 인쇄;

}

else if(test>60)

{

"good" 인쇄;

}

else

{

"통과 없음" 인쇄;

}

}'


매우 좋음



각 명령문은 ";" 기호로 끝날 수 있습니다.



2. 반복문(while, for, do)


1.while문


형식:


while(표현식)


{문}

예:


[chengmo@localhost nginx]# awk 'BEGIN{

test=100;

total=0;

while(i<=test)

{

total+=i;

i++;

}

전체 인쇄

}'

5050

2.


for 루프에는 두 가지 형식이 있습니다.


형식 1:


for (배열의 변수)


{statement}


예:


[chengmo@localhost nginx]# awk 'BEGIN{

for(k in ENVIRON)

{

print k"=" ENVIRON [k];

}

}'


AWKPATH=.:/usr/share/awk

OLDPWD=/home/web97

SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass

SELINUX_LEVEL_REQUESTED=

SELINUX_ROLE_REQUESTED=

LANG = zh_CN.GB2312


. . . . . .


설명: ENVIRON은 awk 상수이자 하위 전형적인 배열입니다.


형식 2:


for (변수; 조건; 표현식)


{문}


예:


[chengmo@localhost nginx]# awk ' 시작{

total=0;

for(i=0;i<=100;i++)

{

total+=i;

}

전체 인쇄;

}'


5050

3.do 루프


형식:


do


{statement} while (조건)


예:


[chengmo@localhost nginx]# awk 'BEGIN{

total=0;

i=0;

do

{

total+=i;

i++;

}동안(i<=100)

전체 인쇄;

}'

5050


위는 awk 흐름제어문인데 구문으로 보면 C언어와 같다는 것을 알 수 있습니다. 이러한 명령문을 사용하면 실제로 많은 쉘 프로그램을 awk로 전달할 수 있으며 성능이 매우 빠릅니다.


break while이나 for 문에서 break 문을 사용하면 프로그램 루프가 종료됩니다.

continue while 또는 for 문에서 continue 문을 사용하면 프로그램 루프가 다음 반복으로 이동합니다.

next는 입력의 다음 줄을 읽고 스크립트의 맨 위로 돌아갑니다. 이렇게 하면 현재 입력 라인에서 추가 작업을 수행하는 것을 방지할 수 있습니다.

exit 문은 기본 입력 루프를 종료하고 END가 존재하는 경우 제어를 END로 전달합니다. END 규칙이 정의되어 있지 않거나 END에 종료 문이 적용되면 스크립트 실행이 종료됩니다.


NR 및 FNR:

인용:

A. 여러 입력 파일에 대한 awk의 실행 순서는 코드가 첫 번째 파일에 먼저 적용되고(한 줄씩 읽기), 반복된 코드가 두 번째 파일에 적용되고, 세 번째 파일에 적용되는 것입니다.

B. Awk의 여러 입력 파일 실행 순서로 인해 줄 번호 문제가 발생합니다. 첫 번째 파일이 실행되고 다음에 두 번째 파일을 읽을 때 두 번째 파일의 첫 번째 줄은 어떻게 계산합니까? 다시 1로 세면 1이 2개 있지 않을까요? (첫 번째 파일에도 첫 번째 줄이 있기 때문입니다.) 이것이 NR과 FNR의 문제입니다.

NR: 전역 줄 번호(두 번째 파일의 첫 번째 줄과 첫 번째 파일의 마지막 줄 번호가 순차적으로 계산됨)

FNR: 현재 파일 자체의 줄 수 (이전 것과 상관없이) 줄 수와 파일 자체의 총 개수를 입력하세요)

예: data1.txt에 40줄, data2.txt에 50줄이 있으면 awk '{} ' data1.txt data2.txt

NR 값은 1, 2...40, 41, 42...90

FNR 값은 다음과 같습니다. 1, 2...40, 1, 2...50

getline 함수 설명:

awk의 getline 문은 단순히 레코드를 읽는 데 사용됩니다. Getline은 사용자가 두 개의 물리적 레코드와 유사한 데이터 레코드를 가지고 있는 경우 특히 유용합니다. 일반 필드의 분리가 완료됩니다(필드 변수 $0 FNR NF NR 설정). 성공하면 1을 반환하고 실패하면 0을 반환합니다(파일 끝에 도달함).

인용문:

A. 일반적으로 getline의 사용법은 다음과 같이 이해해야 합니다.

왼쪽과 오른쪽에 리디렉션 문자나 <가 없으면 getline은 현재 파일의 첫 번째 줄을 읽습니다. 다음 변수에 제공합니다

var 또는 $ 0 (변수 없음); AWK는 Getline을 처리하기 전에 한 줄을 읽었으므로 Getline은

의 반환 결과로 구분되었습니다.

<其> 방향 지정 룬 | 또는 & lt; 또는 & lt; Getline은 파일을 방금 열었기 때문에

에서 한 줄로 읽히지 않습니다. AWK, getline Read in 후 getline은 다른 모든 라인이 아닌 파일의 첫 번째 라인을 반환합니다.

B. getline의 사용법은 대략 세 가지 주요 범주로 나눌 수 있습니다(각 주요 범주는 두 개의 하위 범주로 나뉩니다). 즉, 총 6가지 사용법이 있습니다. 코드는 다음과 같습니다:

인용문:

nawk 'BEGIN{"cat data.txt"|getline d}' data2.txt

nawk 'BEGIN {"cat data.txt"|getline; print $0}' data2.txt

nawk 'BEGIN{getline d < "data.txt" print d}' data2.txt

nawk 'BEGIN {getline < “data.txt”; print $0}' data2.txt

위의 네 줄의 코드는 모두 "data.txt 파일의 첫 번째 줄만 인쇄"를 구현합니다. 모든 줄은 루프를 사용하세요)

예: nawk 'BEGIN{FS=":";while(getline<"/etc/passwd">0){print $1}}' data.txt


인용문:

nawk '{getline d; print d”#”$3}' data.txt

awk는 먼저 첫 번째 줄을 읽습니다. , 그리고 getline 함수를 처리합니다. 그런 다음 변수 d에 다음 줄을 할당하고 d를 먼저 인쇄합니다. d 뒤에 줄 바꿈 문자가 있으므로 다음 #은 d를 덮어쓰고 다음 $3도 d를 덮어씁니다.

인용문:

nawk '{getline; print $0”#”$3}' data.txt

awk는 먼저 첫 번째 줄을 읽은 다음 getline 함수를 처리합니다. 다음 줄은 $0에 할당됩니다. 이제 $0은 다음 줄의 내용입니다. 다음 #과 $3($0에서 가져옴)은 $0의 내용을 덮어씁니다.

awk에서는 awk가 잘 못하는 작업을 완료하기 위해 시스템 도구를 호출해야 하는 경우가 있습니다. awk에서 제공하는 시스템 명령을 사용하여 실행할 수 있지만 외부 도구의 출력 결과를 받을 수 없습니다. 다행히도 getline을 사용하여 이 요구 사항을 충족할 수 있습니다. 예를 들어

test.awk:

{

datecommand="/bin/date -j -f "%d/%b/%Y:%H:% M :%S" " $olddatestr " "+%Y%m%d %H%M%S"";

datecommand | getline newdatestr

close(datecommand);

}

외부 명령은 awk가 파일 설명자를 차지해야 하며 awk가 열 수 있는 최대 파일 수에는 상한이 있으며 크지 않습니다(예: 16) 그러니 마지막으로 마무리를 하는 것은 좋은 습관입니다. 명령 문자열을 변수로 정의하는 것도 종료 시 편의를 위한 것입니다.



awk 명령 및 관련 글에 대한 자세한 설명은 유료로 부탁드립니다. PHP 중국어 웹사이트에 주목하세요!


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.