첫째 날: MS Windows에서 Perl 활용하기

저자

@aer0 - Seoul.pm, #perl-kr의 정신적 지주, Perl에 대한 근원적이면서 깊은 부분까지 놓치지 않고 다루는 홈페이지 및 블로그를 운영하고 있다. aero라는 닉을 사용하기도 한다.

시작하며

Perl이라면 유닉스/리눅스를 떠올리는 분들이 많겠지만 Perl은 프로그래밍 언어들 중에서도 아주 많은 플랫폼에 포팅되어 있는 언어 중 하나입니다. 오늘은 보통 데스크탑으로 많이 쓰는 윈도우즈에서 Perl활용 예를 보여 드릴까 합니다.

윈도우즈용 Perl은 과거부터 Activestate에서 만들어서 배포하는 Activestate Perl과 오픈소스 프로젝트로 진행되고 있는 Strawberry Perl이 대표적입니다. 여기서는 make와 gcc 컴파일러등을 내장해 cpan 유틸리티를 그대로 활용할 수 있고 개인적으로도 선호하는 딸기 펄(Strawberry Perl)을 사용합니다.

딸기 펄 준비

일단 Strawberry Perl에서 Perl 인스톨러를 다운로드해서 설치합니다. 설치시 기본으로 c:\strawberry 아래에 Perl이 설치되고 PATH 환경변수에는 C:\strawberry\c\bin;C:\strawberry\perl\site\bin;C:\strawberry\perl\bin가 추가됩니다. 이 환경변수는 언인스톨러를 사용해 딸기 펄을 제거하더라도 지워지지 않으므로 혹시라도 딸기 펄을 지워야 한다면 PATH 환경변수에서 수동으로 지워주세요.

이제 cmd명령창을 열고 다음 명령을 실행했을때 현재 Perl 버전을 보여준다면 제대로 동작하는 것입니다.

1
c:\> perl -v

따로 hello.pl 스크립트를 작성했다면 다음 명령을 통해서 실행시킬 수 있습니다.

1
c:\> perl hello.pl

펄로 열악한 윈도우즈 쉘의 유틸리티 부재를 극복하자!

각종 유틸리티를 제공해 편리한 유닉스 쉘에 비해 윈도우즈 쉘(cmd)은 상황이 열악하기 그지 없습니다. 제공하는 유틸리티가 부족한 윈도우즈 쉘에서 Perl로 극복하려면 어떻게 해야 할까요?

Perl 설치시 기본으로 제공되는 소소한 유틸리티와 Perl이 제공하는 강력한 원-라이너를 이용하면 윈도우즈에서도 이런 열세를 단번에 극복할 수 있습니다.

개인적으로 리눅스를 사용할 때 가장 많이 쓰는 명령어는 wget, tar, grep입니다. 물론 윈도우즈에서 cygwin이나 윈도우즈용으로 컴파일된 GNU 유틸리티들을 깔고 사용할 수 있지만 자주 사용하는 몇 개의 명령을 사용하고자 따로 설치하기는 번거로운 일입니다. Perl이 설치되어 있다면 따로 유틸리티를 설치하지 않더라도 유사한 작업을 수행할 수 있습니다.

wget의 대체: lwp-download

wgetlwp-download로 대체 가능합니다. 특정 URL의 파일을 다운로드 받는 명령은 다음과 같습니다.

1
c:\> wget http://someurl/file.txt

앞의 명령은 lwp-download를 사용해서 다음처럼 대체할 수 있습니다.

1
c:\> lwp-download http://someurl/file.txt

tar의 대체: ptar

보통 오픈소스 프로젝트 압축파일을 내려 받으면 tar.gz로 압축되어 있는 경우가 많습니다. 이러한 타르볼 압축을 푸는 명령은 다음과 같습니다.

1
c:\> tar -zxvf somefile.tar.gz

앞의 명령은 ptar를 사용해서 다음처럼 대체할 수 있습니다.

1
c:\> ptar -zxvf somefile.tar.gz

grep의 대체: ack

물론 윈도우즈 쉘은 findstr을 제공하지만 grep보다 부족한 기능에 여러분이 적어도(!) grep을 기대했다면 분명 실망할 것입니다. 펄로 grep을 대체하려면 다음처럼 cpan을 실행해서 App::Ack를 설치합니다.

1
2
3
4
5
6
7
c:\> cpan
cpan> force install App::Ack
...
... 설치과정
... (테스트과정에 약간 문제가 있지만 force로 강제설치 - 사용에는 별 문제 없음)...
...
cpan> quit

간단히 다음 명령으로 grep을 대신할 수 있습니다.

1
c:\> ack text_to_find

앞의 명령은 현재 디렉터리 하위의 모든 디렉터리를 다 뒤져서 text_to_find 문자열을 찾습니다. ack는 특정 언어 및 파일 타입 지정해서 검색을 수행하는 등 grep을 사용하면서 한 번쯤은 아쉬워 했을 가려운 부분을 긁어줄 수 있는 그런 편리하면서도 다양한 기능을 제공합니다. 자세한 사용법은 Ack 공식 홈페이지를 참고하세요.

원-라이너 명령행 도구

더불어 Perl은 막강한 원-라이너를 자랑합니다. 그래서 원-라이너를 강력한 명령행 툴로 사용할 수 있습니다. 펄 원-라이너에 대해서 잘 모른다면 원-라이너에 대해서 상세하게 설명한 다음 참고 자료를 확인하세요.

예를 들어 grep처럼 파일에서 어떤 문자열이 있는지 알아보려면 다음 명령을 사용합니다.

1
C:\> perl -ne 'print if /text_to_find/' some.txt

파일 내의 특정 문자열을 다른 문자열로 교체하려면 다음 명령을 사용합니다.

1
C:\> perl -pi -e 's/from/to/g' some.txt

그런데 여기서 주의해야 할 점을 유닉스에서는 앞의 예제처럼 원-라이너 펄 코드를 작은따옴표(')로 묶지만 윈도우즈에서는 오류가 발생하기 때문에 작은따옴표 대신 큰따옴표(")로 묶어줘야 한다는 것입니다. 따라서 앞의 원-라이너 코드는 다음처럼 변경되어야 합니다.

1
C:\> perl -pi -e "s/from/to/g" some.txt

하지만 다음 예제처럼 원-라이너 안에서 큰따옴표가 필요하면 어떻해야 할까요?

1
C:\> perl -lne 'print "$. $_" if /^use/' some.txt

앞의 예제처럼 use로 시작하는 줄을 줄번호와 내용을 함께 찍는 경우에 이것을 윈도우즈용으로 바꾸기 위해 작은따옴표 대신 큰따옴표로 전체 코드를 둘러싸면 " " 내부에 또 "가 들어가기 때문에 문제가 생깁니다.

이때는 다음처럼 역따옴표 회피 문자열을 사용하면됩니다.

1
C:\> perl -lne "print \"$. $_\" if /^use/" some.txt

하지만 이렇게 일일이 회피 문자열을 사용하는 것은 가독성도 떨어지고 번거롭기까지 합니다. 이 경우에 펄의 quote-like 연산자qq 연산자를 쓰면 코드를 큰따옴표와 작은따옴표 중 어느 것으로 묶어주는지와 상관없이 일관성을 유지할 수 있습니다. 큰따옴표를 대체하는 qq 연산자를 써서 바꾼 예제는 다음과 같습니다.

1
C:\> perl -lne "print qq{$. $_} if /^use/" some.txt

앞의 예제를 보면 "$. $_"qq{$. $_}로 변경되었습니다. qq 뒤에 { }와 같은 구분자 사용과 관련한 규칙은 KLDP의 펄 관련 쓰레드에 예전에 올려둔 답글을 참고하세요.

자세한 원-라이너와 관련한 내용은 perlrun 매뉴얼을 확인하세요. 명령줄에서 perlrun 매뉴얼을 확인하려면 다음 명령을 이용합니다.

1
C:\> perldoc perlrun

쪽지시험

그럼 정리하는 의미에서 문제를 하나 내보겠습니다.

KLDP의 "파일 이름을 일괄적으로 바꾸기" 글타래에 있는 다음 명령을 윈도우즈용으로 바꿔보세요.

1
$ ls *.jpg | perl -nle 'system "mv $_ ".do { s/\d+/sprintf("%05d",$&)/e; $_ }'

ls *.jpg는 윈도우즈에서는 dir /b /d *.jpg로 파일 이름만 세로로 출력해 Perl에게 넘겨줄 수 있고, mv 명령은 윈도우에서 move로 대체하면 됩니다. 이제 윈도우즈에서도 동작할 수 있도록 스스로 한 번 바꿔보세요. ;-)

내일은 @ainvyu님께서 수고해주실 겁니다. 바톤 터치~~