1. a2p(awk-perl 변환) |
1) 경로 : /usr/bin/a2p
2) 요약 : awk 스크립트를 perl 스크립트로 변경
3) 사용 방법 : a2p [옵션] 파일명
4) 옵션
-F<문자> : 구분자를 정의. awk의 필드를 나누는 기준이 되는 구분자 변수인 FS 변수를 지정된 문자로 정의
-o : awk 형식의 스크립트를 변환
5) 추가 설명
awk 스크립트를 perl 스크립트로 변환하는 명령어입니다. awk 명령어에서 예제로 만든 work.awk 스크립트를 가져와 변환해 봅니다. 이 예제는 문서의 단어 개수를 체크하는 스크립트 입니다. wordcount.txt 문서의 단어 개수를 확인해 봅시다.
# awk -F word.awk wordcount.txt
Word Count : 580
a2p 명령어를 이용하여 awk 스크립트를 perl 스크립트로 변환합니다.
# a2p wrd.awk
#!/usr/bin/perl
eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
if $running_under_some_shell;
# this emulates #1 processing on NIH machines.
# (remove #! line above if indigestible)
eval '$'.$1.'$2;' while $ARGV[0] = ~/^([A-Za-z_0-9]+=)(.*)/ && shift;
# process any FOO=bar switches
$[ = 1; # set array base to 1
$, = ' '; # set output field separator
$\ = "\n"; # set output record separator
$word = 0;
while (<>) {
chomp; # strip record separator
@Fld = split(' ', $_, -1);
$word += $#Fld;
}
print 'Word Count: ' . $word;
($End);
a2p는 awk 스크립트를 perl 스크립트로 변환하여 화면에 출력합니다. 이 표준 출력을 word.perl 이라는 perl 스크립트 파일로 만들어 실행하면 같은 결과를 얻을 수 있습니다.
# a2p word.awk > worl.perl
#perl word.perl wordcount.txt
Word Count : 580
2. awk(패턴 처리 언어) |
1) 경로 : /bin/awk
2) 요약 : 원본 문서에서 패턴을 검사해 원하는 값을 얻음
3) 사용 방법 : awk [옵션] -F 'script' [변수=값] [파일]
awk [옵션] -f 스크립트 파일 [변수=값] [파일]
4) 옵션
스크립트 파일 : awk 스크립트로 작성된 파일
변수 : awk 내의 변수를 지정
파일 : 대상 파일
-F : 구분자를 나타냄. -F로 구분자를 지정하지 않을 경우에는 공백을 구분자로 사용
-f : 스크립트 파일을 이용할 경우 사용
5) 추가 설명
표준 입력으로 값을 받아 awk 스크립트를 통해 원하는 표준 출력을 내보낼 수 있습니다. awk는 1977년 AT&T 연구소의 Alfred V. Aho, Peter J. Weinverger, Brian W. Kernighan 세 사람이 만들었습니다. awk라는 이름도 세 사람 이름의 앞 글자를 가져와서 지었습니다. 이 후 1986년 Paul Rubin과 Jay Fenlason이 GNU 버전의 awk를 만들어서 리눅스에서 사용했습니다.
awk는 일정한 규칙을 가지고 있는 데이터를 처리하여 계산, 통계, 비교 분석, 필터링을 통한 데이터 추출 등에 다양하게 사용될 수 있습니다. sed와 비슷한 기능을 한다고 할 수 있으며 awk와 sed의 장점을 묶어서 perl로 발전시켰지만 데이터 구조가 단순할 때는 awk가 더 효과적이어서 지금도 많이 사용하고 있습니다.
awk는 단순히 명령어로 사용되거나, 스크립트 내에서 sed와 함께 이용될 수 있고 awk만의 스크립트 파일을 작성할 수도 있습니다. 현재 디렉터리에 있는 파일 목록을 보기 위해 ls -al 명열을 사용합니다.
# ls -al
total 8
drwxr-xr-x 2 chan chan 4096 Mar 31 16:40 Desktop
-rw-r--r-- 1 chan chan 15 Mar 31 16:43 chan_test
ls -al 명령을 사용해서 현재 디렉터리에 있는 파일 목록을 본 다음에 awk를 사용하여 이 목록 중 파일 권한과 파일명만 출력할 수 있습니다. ls -al 명령으로 출력되는 데이터를 파이프(|)로 awk가 받아서 파일의 공백을 기준으로 나누어 첫 번째 필드와 아홉 번째 필드만 출력합니다.
# ls -al
total 8
drwxr-xr-x 2 chan chan 4096 Mar 31 16:40 Desktop
-rw-r--r-- 1 chan chan 15 Mar 31 16:43 chan_test
# ls -al | awk '{print $1, $9}'
total
drwxr-xr-x Desktop
-rw-r--r-- chan_test
위와 같이 awk는 라인을 받아서 구분자를 통해 구분하고, print 명령으로 출력하게 됩니다. ls -al로 출력되는 행을 공백으로 구분하면 아래오 ㅏ같이 $1~$9 까지 필드로 나뉩니다. 각 필드는 공백을 기준으로 아래처럼 번호로 구분됩니다. $0은 모든 필드를말합니다.
-rw------ | 2 | root | root | 23376 | Mar | 31 | 16:46 | mbox |
파일권한 | 하드링크번호 | 사용자 | 그룹 | 용량 | 월 | 일 | 시간 | 파일명 |
$1 | $2 | $3 | $4 | $5 | $6 | $7 | $8 | $9 |
파일 목록 중 1MB가 넘는 파일의 파일명과 용량을 출력하고 싶다면 awk의 조건문을 사용하면 됩니다. 용량을 나타내는 다섯 번째 필드값이 1,048,576(1MB) 보다 큰 숫자를 갖고 있는 라인의 다섯 번째와 아홉 번째 필드만 출력합니다.
# ls -al | awk '$5 > 1048576{print $5, $9}'
5782608 libqt-mt.so.2.3
5761541 libqt.so.2.3.2
1698368 memory_info
이 처럼 검색하여 특정 라인과 필드만 출력할 수 있습니다. awk를 이용하면 문서의 특정 문자나 문자열을 검색하여 그 부분만 출력할 수 있습니다. 예를 들어 다음과 같이 하면 /etc/group 파일에서 root를 포함한 라인만 출력합니다.
# awk /root/ /etc//group
root:x:0:root
bin:x:1:root,bin,daemon
daemon:x:2:root,bin,daemon
... 중간 생략 ...
adm:x:4:root,adm,daemon
disk:x:6:root
wheel:x:10:root
위 출력 결과에서 ":"을 구분자로 하여 분리한 필드 중 첫 번째 필드만 출력하는 awk 명령어를 만들어 봅니다. 첫 번째 필드는 그룹명이고 -F 옵션을 사용해서 ":"를 구분자로 지정합니다.
# awk -F: /root/'{print $1}' /etc/group
root
bin
daemon
sys
adm
disk
wheel
/root/ 로 검색한 패턴 부분에 정규 표현식을 사용하면 더욱 자세한 패턴을 검색할 수 있습니다.
<스크립트 파일 이용>
awk의 스크립트 구조는 시작, 실행, 마무리의 3단계로 나누어져 있습니다. awk는 연산자나 루프 사용법 등이 C 언어와 같아 C언어를 알고 있는 사용자라면 쉽게 사용할 수 있습니다.
시작(Begin) | 시작 단계로서 전체 스크립트를 위한 정의 단계(Preprocessor) |
실행(Routin) | 실행 단계로 이 스크립트의 기능을 수행하는 단계 |
끝(End) | 마무리 단계로 결과를 출력 |
word.awk라는 이름으로 파일 내에 단어의 개수를 알아보는 awk 스크립트를 만들어 봅니다. 사실 단어 개수를 셀 때는 wc 명령어를 사용하면 쉽습니다.
#!/bin/awk
BEGIN {
wrod = 0;
}
{ word += NF;}
END { print "Word Count: " word;(End)}
awk 스크립트의 구조를 분석하면 아래와 같이 나눌 수 있습니다.
awk 스크립트 | 구조 | 실행 |
#!/bin/awk | 선언 | awk로 스크립트가 실행될 수 있게 선언 |
BEGIN { word = 0; } |
시작 | 변수 wrd를 0으로 초기화 |
{ word += NF;} |
실행 |
NF는 각 라인 마다의 필드 수를 나타내는 awk 시스템 변수. 구분자 정의가 없으면 공백을 구분자로 사용하므로 각 라인의 단어 수가 NF로 들어가고 "+=" 연산자에 의해서 마지막 라인의 단어 수 까지 더해줌 |
END { print "Word Count: " word;(End)} |
씇 |
마무리 단계. 결과를 출력 |
작성된 스크립트는 -f 옵션으로 실행합니다. wordcount.txt 라는 임의의 텍스트 문서를 방금 지정한 스크립트로 검사해 봅니다. 작성된 awk 스크립트 파일은 awk -f [스크립트 파일] [대상 파일]로 실행합니다.
# awk -f word.awk wordcount.txt
Word Count : 580
<awk 시스템 변수>
변수 | 내용 |
$0 | 입력 라인 모두 |
$n | 입력 라인에서 n번째 필드 값 |
ARGC | 명령 라인 인자 수를 갖는 변수 |
ARGV | 명령 라인 인자 수를 갖는 변수 |
ENVIRON | 환경 변수들을 모아둔 관계형 배열 |
FILENAME | 현재 파일명 |
FS | 구분자 정의. 공백을 기본으로 사용 |
FNR | 입력 파일의 레코드 총수(라인 수) |
NF | 현재 레코드 필드 수 |
NR | 현재 레코드 번호 |
OFMT | 숫자에 대한 출력 포맷 |
OFS | 출력 필드 구분. 빈 라인을 기본으로 사용 |
ORS | 출력 레코드 부분 (newline을 기본으로 사용) |
RLENGTH | 지정한 패턴으로 검색되어 나온 문자열의 길이 |
RS | 입력 레코드 구분(newline을 기본으로 사용) |
RSTART | 지정한 패턴으로 검색되어 나온 문자열의 가장 앞부분 |
<awk 연산자>
C 언어를 참조하여 만들어 졌으므로 C 언어와 사용법이나 종류가 거의 같습니다.
연산자 | 설명 |
? |
조건연산 사용자로 등록된 아이디가 user1, user2, user3으로 되어 있고 그 중 검색하고 싶은 내용이 1/2/3 중 어떤 것일지 명확하지 않을 경우 ?를 이용하여 모두 검색할 수 있습니다.
# awk/user?/etc/passwd user1:x:516:516::/home/user1:/bin/bash user2:x:517:517::/home/user2:/bin/bash user3:x:518:518::/home/user3:/bin/bash |
||, $$, ! |
논리 연산자. or, and, not |
~,!~ |
검색된 패턴에 부합되는 것을 참으로 사용하려면 "~", 거짓으로 사용하려면 "!~"을 사용 |
<. <=, >=, !=, == |
비교 연산자 |
+, -, *, /, %, ^ |
더하기, 빼기, 곱학, 나누기, 나머지, 제곱 |
++, -- |
증가 연산자. 감소 연산자 |
3. cmp(파일 비교) |
1) 경로 : /usr/bin/cmp
2) 요약 : 파일을 비교하여 다른 부분을 알려 줌
3) 사용 방법 : cmp [옵션]
4) 옵션
-l(엘) : 각 차이점에 대한 바이트 넘버와 다른 바이트 값을 출력
-s : 아무런 메시지를 출력하지 않음. 단지 종료 상태만 남김(0 : 차이 없음, 1 : 차이점 있음)
5) 추가 설명
cmp 명령어는 diff 명령어의 간단한 버전이라고 할 수 있습니다. diff가 두 파일 간의 차이점을 상세하게 보여 주는 반면, cmp는 차이점이 있고 없고 만을 확인할 수 있습니다.
cmp를 이요한 파일 비교를 위해 간단한 텍스트 파일을 만들어 봅니다. echo 명령을 이용하여 간단한 텍스트가 삽입된 파일을 만들어 봅니다.
# echo "hello world" > cmo_test
# echo "hello world friend" > cmp_test2
두 파일을 cmp 명령으로 비교합니다. 첫 번째 줄의 열두 번째 글자부터 다르다는 것을 표시해 줍니다.
# cmp cmp_test cmp_test2
cmp_test cmp_test2 differ: char 12, line 1
4. col(개행 문자 변환) |
1) 경로 : /usr/bin/col
2) 요약 : 텍스트 파일의 개행 문자와 공백 문자 등을 변환하여 문서 속성을 변경
3) 사용 방법 : col [옵션]
4) 옵션
-b : 어떠한 백스페이스 문자도 출력하지 않고, 각 열 위치에 쓰여진 마지막 문자만을 출력
-h : 중복되는 공백을 출력하지 않음
-x : 탭을 대신하여 여러 스페이스로 변경하여 출력
-l(엘) 숫자 : 버퍼 값을 지정. 메모리에 한 번에 올릴 수 있는 최대 줄 수를 지정. 초기값은 128줄
5) 추가 설명
col 필터는 \n\r 문자를 \n 문자로 바꾸거나 공백 문자를 탭 문자로, 백스페이스 문자를 없애는 기능을 합니다.
아래는 맨 페이지를 입력으로 받아들여 파일로 저장한 예입니다.
# man httpd | col > httpd.man
5. colcrt(밑줄 문자 변환) |
1) 경로 : /usr/bin/colcrt
2) 요약 : 밑줄(_) 문자를 감추거나 다음 줄에 반줄(-) 속성으로 변환해 주는 필터
3) 사용 방법 : colcrt [옵션] [파일]
4) 옵션
- : 밑줄 속성이 있는 문자열을 출력하지 않음
-2 : 인쇄상 줄 간격이 이상한 오류가 발생하기 때문에, 밑줄 속성이 있는 줄의 다음 줄에 반줄(-) 속성을 부여하엿고, 없는 줄에는 공백 줄을 추가
5) 추가 설명
colcrt 필터는 밑줄(_) 속성을 반줄(-) 속성으로 바꾸어 주거나, 밑줄 속성을 보이지 않게 할 수 있습니다. 예를 들어 현재 query라는 파일에는 밑줄 문자가 3개가 포함되어 있다고 가정합니다. data_format과 cst_users, cst_productregs 문자입니다.
# cat query
select data_format(uregdate, '%y%m') date,count(uid) from cst_users u, cst_productregs p, cst-productregdetail d
where u.uno=p.preguno
and p.pregno=d.preggno
colcrt 필터를 사용하며 밑줄 문자가 한 줄 아래(_)로 표시된 것을 볼 수 있습니다.
# cat query | colcrt
select data_format(uregdate, '%y%m') date,count(uid) from cst_users u, cst_productregs p, cst-productregdetail d
_ _ _
where u.uno=p.preguno
and p.pregno=d.preggno
colcrt -은 밑줄 문자를 출력하지 않게 해줍니다.
# cat query | colcrt -
select data_format(uregdate, '%y%m') date,count(uid) from cst_users u, cst_productregs p, cst-productregdetail d
where u.uno=p.preguno
and p.pregno=d.preggno
-2 옵션은 밑줄 속성이 있는 줄의 다음 줄에 (-) 속성을 부여하고, 없는 줄에는 공백 줄을 추가합니다.
# cat query
select data_format(uregdate, '%y%m') date,count(uid) from cst_users u, cst_productregs p, cst-productregdetail d
- - -
where u.uno=p.preguno
and p.pregno=d.preggno
'IT 이야기 > Linux 명령어' 카테고리의 다른 글
[RHEL6] 파일 조작 명령어 3탄(expand, hexdump, join, look, nl) (0) | 2020.03.31 |
---|---|
[RHEL6] 파일 조작 명령어 2탄(colrm, column, comm, csplit, cut) (0) | 2020.03.31 |
[RHEL6] 파일 보기 명령어 3탄(pathchk, size, sum, tail, tailf) (0) | 2020.03.27 |
[RHEL6] 파일 보기 명령어 2탄(ispell, less, lsattr, more, namei) (0) | 2020.03.27 |
[RHEL6] 파일 보기 명령어 1탄(access, cat, chattr, file, head) (0) | 2020.03.27 |
댓글