awk 입문 및 진급

5456 단어 Shell
awk 는 Linux 에서 우수한 텍스트 처리 도구 로 자체 적 으로 하나 가 되 는 프로 그래 밍 문법 규칙 이 있 으 며 순환 과 조건 판단 문 등에 서 C 언어 와 매우 비슷 하 다.
그 일반적인 형식 은 Pattern 1 {ACTIONS;} Pattern 2 {ACTIONS;} 이다. 그 중에서 Pattern 은 조건 (if 문장 과 유사) 으로 이해 할 수 있 고 해당 조건 을 만족 시 킬 때 해당 하 는 ACTIONS 를 집행 한다.
awk 의 기능 이 매우 강하 고 관련 된 내용 도 매우 광범 위 하 다. 다음은 필자 가 가장 중요 하고 자주 사용 하 는 내용 만 기술 하 겠 다. 
1. 관건 내 장 된 매개 변수 와 명령 블록
내 장 된 인자:
FS: 입력 필드 구분자, 기본 값 은 빈 칸 입 니 다.
OFS: 출력 필드 구분자, 기본 값 도 공백
NF: 줄 당 ($0) 보유 한 칸 의 갯 수
NR: 총 "몇 번 째 줄"을 처리 합 니 다.
FNR: 현재 파일 의 "몇 번 째 줄"을 처리 합 니 다.
메모: 파일 이 하나 밖 에 없 을 때 FNR 은 NR 와 같 습 니 다.
명령 블록:
BEGIN {}: 줄 별로 파일 을 처리 하기 전에 BEGIN 블록 내 명령 을 실행 합 니 다. 일반적으로 관련 인 자 를 초기 화 하 는 데 사 용 됩 니 다.
END {}: 줄 에 따라 파일 을 처리 한 후에 END 블록 내 명령 을 실행 합 니 다. 보통 최종 결 과 를 출력 합 니 다. 
2. 이해 행 별 처리
awk 를 사용 할 때 {ACTIONS} 이 각 줄 의 처리 동작 에 대응 하 는 것 을 명확 하 게 해 야 합 니 다.그리고 더욱 강력 한 것 은 각 줄 의 정 보 를 변수 에 보관 하여 후속 적 으로 사용 할 수 있다 는 것 이다.
예제 (a): passwd 파일 내용 을 입력 하고 FS = ":"구분자 가 콜론 으로 지정 합 니 다.세 번 째 필드 $3 < 10 시 인쇄 $1 과 $3 의 작업 을 수행 합 니 다.
4. 567913. 예제 (b): 판매 문서 xs 중의 판매 총 금액 을 계산 합 니 다. 판매 금액 이 기 록 된 세 번 째 필드 에 있다 고 가정 하고 총 금액 은 변수 totalk 에 저장 하 며 마지막 으로 판매 금액 의 총 계 를 출력 합 니 다.
cat /etc/passwd | \
awk 'BEGIN {
FS=":"
}
$3 < 10 {
print $1"\t " $3
}'

3. 배열 의 사용
개인 적 으로 배열 은 awk 에서 가장 유용 한 데이터 구조 로 awk 의 효능 을 크게 향상 시 켰 다 고 생각 합 니 다.awk 의 배열 아래 표 시 는 숫자 나 알파벳 으로 관련 배열 이 라 고 할 수 있 으 며, python 의 사전 형식 과 유사 하 게 계수, 저장 을 보조 할 수 있 습 니 다.
ü  변 수 를 배열 로 표시 합 니 다.예: $awk {name [x +] = $2};END{for(i=0;i
ü  for 순환 은 관련 배열 의 요 소 를 읽 는 데 사 용 됩 니 다. 형식 은 다음 과 같 습 니 다.
$awk -F ":" '{
print $3; #打印每一行的销售金额
total=total+$3;
}
END {
printf "销售金额总计:%.2f",total #打印总销售金额
}' xs

ü  다음 문자열 로 표시 합 니 다. 예 를 들 어 count ["test"]
ü  도 메 인 값 을 배열 의 아래 표 시 를 사용 합 니 다. for (index value in array) statement 의 새로운 for 순환 방식 입 니 다. 예 를 들 어 awk '{count [$1]++} END {for (name in count) print name, count [name]}' test. 이 문 구 는 $1 의 다른 문자열 이 나타 나 는 횟수 를 인쇄 합 니 다. 먼저 첫 번 째 도 메 인 을 배열 count 의 아래 표 시 를 하고 첫 번 째 도 메 인 내용 이 변 하면 색인 이 변 합 니 다.
ü  delete 함 수 는 배열 요 소 를 삭제 하 는 데 사 용 됩 니 다. 예 를 들 어 $awk '{line [x +] = $1} END {for (x in line) delete (line [x])}' test. 배열 line 에 분 배 된 값 은 첫 번 째 필드 의 값 입 니 다. 모든 기록 처리 가 완료 되면 for 순환 은 모든 요 소 를 삭제 합 니 다.
응용 예:
NR = = = FNR 에서 이전 파일 을 처리 하고 NR > FNR 에서 다음 파일 을 처리 하 는 두 개의 파일 을 배열 로 통합 합 니 다.
{
for (item in arrayname){
print arrayname[item]
}
}
#使用数组遍历输出所有以tom开头的行。
$ awk'/^tom/{
name[NR]=$1
};
END{
for(i in name){
printname[i]
}
}' test

4. 정규 일치 적용
awk 를 사용 하여 파일 을 처리 할 때 항상 이러한 요구 가 있 습 니 다. 줄 에 특정한 문자열 이 포함 되 어 있 을 때 해당 하 는 작업 을 합 니 다. 정규 일치 하 는 원 리 는 간단 하지만 기능 이 상당히 강 합 니 다. 다음은 범례 를 직접 사용 하여 설명 합 니 다.
범례 참조:http://www.cnblogs.com/zhuyp1015/archive/2012/07/14/2591822.html
처리 해 야 할 파일 "grade. txt"가 있다 고 가정 합 니 다.
M.Tansley         05/99        48311       Green       8       40     44
J.Lulu        06/99        48317       green        9       24     26
P.Bunny    02/99        48     Yellow       12     35     28
J.Troll        07/99        4842         Brown-3   12     26     26
L.Tansley  05/99        4712         Brown-2   12     30     28
awk -F ","  'BEGIN{
OFS=","
}
NR==FNR{
a[$1]=$0 # $1为第一个文件中的userid字段
}
NR>FNR && NF>3{ #行字段大于3个的行
gsub("","",$3);
if(a[$3]!="")print $0,a[$3] #$3为第二个文件的userid字段
}' file1 file2

5. 포맷 출력
대부분의 경우 print 를 사용 하면 문 제 를 해결 할 수 있 지만, 때때로 포맷 출력 을 사용 해 야 합 니 다. awk 의 printf () 와 sprintf () 는 포맷 출력 을 할 수 있 습 니 다. 문법 규칙 은 C 언어 와 거의 같 습 니 다.
printf () 는 stdout 에 문자열 을 인쇄 합 니 다. printf () 를 사용 할 때 print () 처럼 줄 바 꿈 자 를 자동 으로 인쇄 하지 않 습 니 다. 문자열 끝 에 '' 기 호 를 추가 해 야 합 니 다.
#非精确匹配,第3个字段包含“48”时则打印
$ awk '$3 ~/48/ {print $0}' grade.txt
#精确匹配,第3个字段等于48时则打印
$ awk '$3=="48" {print $0}'grade.txt
#不区分首字母的大小写,匹配含Green或者green的行
$ awk '/[Gg]reen/' grade.txt
#匹配第一个域的第四个字符是‘a’的行
$ awk '$1 ~/^...a/' grade.txt
# “或”匹配,使用‘|’
$ awk '$0 ~/(Yellow|Brown)/' grade.txt
#也可以这样,不加括号
$ awk '$0 ~/Yellow|Brown/' grade.txt

sprintf () 는 변수 에 할당 할 수 있 는 포맷 문자열 을 되 돌려 줍 니 다.
Format 매개 변수 가 지정 한 sprintf 하위 루틴 형식 문자열 에 따라 Expr 매개 변수 가 지정 한 표현 식 을 포맷 하고 마지막 으로 생 성 된 문자열 을 되 돌려 줍 니 다.
# cat grade.txt | \
awk 'NR==1{printf "%10s %10s %10s %10s%10s
",$1,$2,$3,$4,"Total" }

6. 셸 변수의 인용
awk 에서 자신의 변 수 를 인용 하 는 것 처럼 셸 변 수 를 인용 할 수 없습니다. 사용 가능 한 인용 방식 은 다음 과 같 습 니 다.
(1) 따옴표 '$var' 사용 하기
이러한 표기 법 은 모두 가 awk 프로그램 을 포함 하 는 습관 을 바 꿀 필요 가 없 으 며, 외국인 들 이 자주 사용 하 는 표기 법 이다. 예 를 들 어:
sprintf(Format, Expr, Expr, . . . )
cat grade.txt |awk'NR==1{a=sprintf("%10s
",$3); print a}'

(2) 사용 - v 옵션
셸 에 var = "this is a test"가 있다 고 가정 하면 awk 에서 이렇게 참조 할 수 있 습 니 다.
var="test"
awk 'BEGIN{print "'$var'"}'

7. 코드 가 독성 증가
어떤 사람들 은 모든 awk 문 구 를 한 줄 에 쓰 고 주석 이 없 는 습관 이 있 습 니 다. 간단 한 기능 만 실현 하려 면 문제 가 없 지만 실현 해 야 할 기능 이 복잡 할 때 코드 의 읽 기, 유지 와 재 활용 에 불리 합 니 다.
코드 의 가 독성 을 증가 시 키 는 데 다음 과 같은 몇 가지 측면 이 있 습 니 다.
1) 주석 사용: bash 와 마찬가지 로 awk 의 주석 기호 도 '\#' 입 니 다.
2) 들 여 쓰기 와 줄 바 꾸 기 사용: awk 에서 줄 바 꾸 기와 들 여 쓰기 가 코드 의 실행 에 영향 을 주지 않 고 좋 은 레이아웃 은 가 독성 을 크게 향상 시 킬 수 있 습 니 다.
 

좋은 웹페이지 즐겨찾기