DATA 전문가로 가는 길

[ Perl ] Perl Oneliners [Pattern, Select, Change] 본문

Programming/Perl

[ Perl ] Perl Oneliners [Pattern, Select, Change]

EstenPark 2010. 11. 30. 16:05
작성자 : 박상수
작성일자 : 2010.11.30
작업환경 : VMware7 [ Solaris 9 ]
참고자료 : HOT PERL ONELINES

1. 원하는 필드만 출력(Pattern)
[설명] 원본 데이터 보기 
# perl -lane 'print $_' passwd
root:x:0:1:Super-User:/:/bin/bash
daemon:x:1:1::/:
bin:x:2:2::/usr/bin:
sys:x:3:3::/:
adm:x:4:4:Admin:/var/adm:

[설명] 패턴(:)을 기준으로 1번째 데이터를 각 라인에 출력, $F[숫자입력] 하면 각각 필드의 값만 출력 합니다.
# perl -F/\:/ -lane 'print $F[0]' passwd
root
daemon
bin
sys
adm

[설명] 위와 비슷한 패턴이며 1번째 필드를 보여 주고 탭을 이용하는 방법입니다. $F[숫자입력] \[t,n] 사용할 수 있습니다.
# perl -F/\:/ -ane 'printf "$F[0] \t" ' passwd
root    daemon  bin     sys     adm



2. 문자열 조회(String)
[설명] 원본 데이터 보기 
# perl -lane 'print $_' passwd
root:x:0:1:Super-User:/:/bin/bash
daemon:x:1:1::/:
bin:x:2:2::/usr/bin:
sys:x:3:3::/:
adm:x:4:4:Admin:/var/adm:

[설명] 1..4 의미는 1부터 4번째 라인만 출력 하기 위한 방법입니다.
# perl -ne 'print if 1..4' passwd
root:x:0:1:Super-User:/:/bin/bash
daemon:x:1:1::/:
bin:x:2:2::/usr/bin:
sys:x:3:3::/:

[설명] passwd 파일의 1부터 4번 라인을 출력 후 번호를 부여 하는 방법입니다.
# perl -ne 'printf "$. $_" if 1..4' passwd
1 root:x:0:1:Super-User:/:/bin/bash
2 daemon:x:1:1::/:
3 bin:x:2:2::/usr/bin:
4 sys:x:3:3::/:


[설명] 첫라인이 root이거나 bin만 출력 하고 파일의 라인번호를 알아내는 방법입니다. 설명을 하자면 $.(파일번호), $_(문자열출력)을 의미 하며 if /   / 안에 정규표현식을 넣으면 되는데 아래와 같은 경우에는 ^(첫번째 문자열중에서...) root, bin 문자열이 있으면 출력하게 됩니다.
# perl -ne 'printf "$. $_" if /^(root|bin).+/' passwd
1 root:x:0:1:Super-User:/:/bin/bash
3 bin:x:2:2::/usr/bin:


[설명] paaswd 파일에서 /bin/bash 쉘이나 /bin/sbin/sh 쉘을 사용하는 문자열을 출력 해보도록 하겠습니다.
이번 perl oneliner는 좀 어려울 수 있습니다. 기본적으로 알아야 할 부분은 \(와일드카드) 역활을 하게 하고 특수문자 Meta character를 문자열로 변경해 주게 됩니다. 그래서 .+\: 의미는 문자의 앞에는 특수문자든 영문이든 숫자든 모두 포함하고 :로 시작 하는 문자열을 의미하며 (\/bin...)$ 의미는 /bin/bash, /bin/sbin/sh 2개의 문자열이 마지막에 나오는 데이터만 출력 하겠다는 의미입니다.
# perl -ne 'printf "$. $_" if /.+\:(\/bin\/bash|\/bin\/sbin\/sh)$/' passwd
1 root:x:0:1:Super-User:/:/bin/bash

[설명] string 원본 파일
# cat string
START
Test string
LOG FILE
A
END

ASDF
fasdf
asdf
[설명] string 파일에서 START로 시작해서 END로 끝나는 문자를 제외한 나머지를 보고 싶을 경우 아래와 같이 하시면 됩니다.
# perl -ne 'printf"$. $_" unless /^START$/../^END$/' string
6
7 ASDF
8 fasdf
9 asdf
10

[설명] string 파일에서 START로 시작해서 END로 끝나는 문자열을 보고 싶을때 아래와 같이 하시면 됩니다.
# perl -ne 'printf"$. $_" if /^START$/../^END$/' string
1 START
2 Test string
3 LOG FILE
4 A
5 END



2. 문자열 치환
[설명] 원본 데이터 보기 
# perl -lane 'print $_' passwd
root:x:0:1:Super-User:/:/bin/bash
daemon:x:1:1::/:
bin:x:2:2::/usr/bin:
sys:x:3:3::/:
adm:x:4:4:Admin:/var/adm:

[설명] sed를 사용해서 하는 작업을 perl로 해봤습니다. sed도 좋은 유틸리티 이지만 나중에 정말 복잡한 문자열을 치한 하게 되면 이런저런 잡머리를 써야 해결이 되실 겁니다. -i 옵션을 주고 해당 문자열을 찾아서 변경 해준다. 하지만 반드시 -pe 옵션을 같이 사용해야 한다. 그러한 이유는 perl --help를 확인 해보시기 바랍니다.
# perl -i -pe 's/root/oracle/g' passwd

변경 전 : root:x:0:1:Super-User:/:/bin/bash
변경 후 : oracle:x:0:1:Super-User:/:/bin/bash

[설명] 위와 동일한 명령어 이며 -i 옵션에 .[파일이름]을 넣어줄 경우 백업 파일을 만들어 줍니다. 지금은 1개의 파일을 변경 했지만 현업에서는 수십만개의 파일을 변경한다고 생각하면 백업 파일을 만들어 주는게 도움이 될 수도 있습니다.
# perl -i.back -pe 's/oracle/root/g' passwd

변경 전 : oracle:x:0:1:Super-User:/:/bin/bash
변경 후 : root:x:0:1:Super-User:/:/bin/bash

# ls passwd*
passwd       passwd.back



4. 문자열 찾기

[설명] AUX, Solaris 운영서버에서 로그파일 확인 후 대처하는 작업을 상당해 많이 했습니다. 그런데 일일이 디렉토리 들어가서 확인 하고 나오고 강아지 노가다가 따로 없었습니다. 아래와 같은 방법 외에 perl로 단독적으로 사용할 수 있는데 그건 문법이 좀 어려워서 3개의 명령어를 이용해서 하위 디렉토리의 *.* 파일을 열어서 smmsp라는 문자열이 있을 경우 출력 하는 방법입니다. xargs 명령어는 linux/unix 모두 사용 가능합니다.

실행과정)
perl -ne 'print if /smmsp/' ./abc.log 
perl -ne 'print if /smmsp/' ./abc.conf
perl -ne 'print if /smmsp/' ./disk/reset.log

# find . -name '*.*' -type f |xargs perl -ne 'print if /smmsp/'
smmsp:x:25:25:SendMail Message Submission Program:/:



 

Perl 정규표현식을 공부 많이하면 지금 위에 있는 내용 보다 더 많이 활용 하실 수 있습니다.
유닉스/리눅스 명령어로 하던 작업을 perl 문법 하나로 모두 할 수 있다는게 가장 큰 매력이 아닐까 생각해봅니다.

단, 옵션을 어떻게 주느냐에 따라서 많이 바뀌고 원하지 않은 답이 나올 수도 있습니다.
각 옵션에 대해서 한번 쯤 찾아보시기 바랍니다.


Comments