DATA 전문가로 가는 길

[Perl] Perl Command-Line Options 본문

Programming/Perl

[Perl] Perl Command-Line Options

EstenPark 2009. 4. 9. 22:41


정규표현식, Perl One Line 등등 공부하다 보니 옵션이 너무  헷갈리고 왜 쓰는지 궁금해서 못하는 영어를 번역 해가며 (구글 변역기) 차례대로 사용법을 익혀 보려 합니다.

perl option 을 보도록 하겠습니다.

1. 실행 제어
-e  : 스크립트로서 실행할 스트링을 지정 하여 Command Line에서 수행
-M : 펄 모듈을 로드하는 옵션이며, Default Import 하지 않을 경우 -m 옵션을 사용
-l   : 표준 장소 앞에서 모듈을 검색하기 위한 디렉토리 지정 
-c  : 펄 프로그램을 컴파일(실행전 에러 체크)

2. 데이터
-0  : (zero) Input Record 구분자 지정(00, 0777)
-a  : split된 결과를 @F 배열에 사용 (-p, -n)
-n  : <>를 사용하여 파일에 레코드 값을 @ARGV 인자로 검색(-p,-e로 정의 및 파일을 한라인씩 처리)
-p  : -n과 동일, $_의 내용을 프린트
-i   : 파일 편집(perldoc perlnum 참조)
-F  : 패턴으로 분활하여 사용(awk -f'|' eq perl -F'|')

3. 위험
-w  : 펄 코드에 대한 에러코드(warning)를 출력 (코드상 use warnings 키워드 사용)

4. 버전
-v   : 버전을 확인 하기 위한 옵션(중요한 펄 정보를 보여줌)
-V   : 버전에 대한 구성을 보여주는 옵션(Config.pm 참조)


Cord Listing 1

 $ perl -e 'print "Hello Word!\n"'
 Hello Word!
-e 옵션을 사용하여 짧은 프로그램을 원라인으로 출력 하는 방법입니다.
echo "Hello Word" |perl -nle 'print' 같은 방법이긴 하지만 크게 중요성을 둬야할 실행문은 아니라고 생각 합니다.

Cord Listing 2-1
 $ cat data.log
20090408-10:20:41 [12434] RST=[0] MSG=[jeen] ERRCODE=[-2151]
20090408-10:20:41 [12434] RST=[2] MSG=[perl] ERRCODE=[-2352]

$ perl -pe 's/MSG/USER/g' data.log
20090408-10:20:41 [12434] RST=[0] USER=[jeen] ERRCODE=[-2151]
20090408-10:20:41 [12434] RST=[2] USER=[perl] ERRCODE=[-2352]
-pe 옵션을 이용한 방법으로 MSG를 USER로 변경 하는 방법입니다.
그렇다고 실제로 파일안에 있는 값을 바꾸지는 않습니다. 위에 설명한 것처럼 출력을 해주기 위한 부분입니다.

Cord Listing 2-2
$ perl -i -pe 's/MSG/USER/g' data.log

$ cat data.log
20090408-10:20:41 [12434] RST=[0] USER=[jeen] ERRCODE=[-2151]
20090408-10:20:41 [12434] RST=[2] USER=[perl] ERRCODE=[-2352]
-i 옵션은 파일안에 있는 내용을 변경하는 방법이라고 생각 하시면 됩니다.
지금은 한 파일안에 있는 String을 수정하였지만 수많은 로그에서 모두 수정을 원한 다면 아래 처럼 하세요.

Cord Listing 2-3
$ perl -i.bak -pe 's/USER/MSG/g' data.log
$ ls -al
-rw-r--r--  1 Administrator Mass 1.1K Apr  9 21:45 data.log
-rw-r--r--  1 Administrator Mass 1.1K Apr  9 21:41 data.log.bak

$ cat data.log
20090408-10:20:41 [12434] RST=[0] MSG=[jeen] ERRCODE=[-2151]
20090408-10:20:41 [12434] RST=[2] MSG=[perl] ERRCODE=[-2352]
-i.bak 적용하면 백업 파일을 만들고 해당 파일을 수정하게 됩니다.
전체 파일을 수정하고 싶으면 *.log 또는 조건에 맞는 정규표현식을 이용하여 변경을 하셔도 됩니다.

Cord Listing 2-etc
aero

원하던 작업이 아니어서 .bak 확장자가 붙어 백업된 파일들을 원본으로 되돌리고 싶다. 그런데 문제는 이 디렉토리 안에 .bak 이 붙은 디렉토리도 있고 원래 .bak의 확장자를 가진 파일도 있었다. 어떻게 하면 이런 복잡한 상황에서 작업 된 파일들만 대상으로 원상복구 작업을 할 수 있을까?

답)
perl -e 'map{ s/.bak//; -f and qx/mv $_.bak $_/ }  <*.bak>'

이것은 .bak확장자의 파일(디렉토리는 제외)을 찾아서 백업된 파일과 변경된 파일이 동시에 존재 할때만 백업본 파일을 원본 파일로 되돌리는 Perl one-liner 이다. 이것을 유닉스쉘이나 기타 스크립트언어들로 하려고 하면 이렇게 간단하게는 힘들 것이다.
위 원라인은 우선 map가 어떤 기능을 하는지 알아야 이해가 갈것입니다.
실제로 aero 님 말 처럼 실행 하는 부분도 중요하지만 백업 하는 부분도 상당히 중요하다고 생각 합니다.
수 많은 파일을 수정 했고 다시 백업 하기 위해서는 위처럼 Perl one-liner을 사용하면 좋을 것입니다.
하지만, 그져 갔다가 쓰는 습관은 좋은 것이 아니기 때문에 가급적이면 코드 분석 후 사용 하는게 나중을 위해 중요한 결실? 입니다. 실력이라는게 그져 남들에게 보여주는 것 만이 다가 아닌 ....(여기서 헛소리를;;)

Cord Listing 3-1

$ ls -al |perl -ne 'next if /^d/; $sum += (split)[4]; END{ printf"%.f \n",$sum }'
3690

$ ls -al |perl -ane 'next if /^d/; $sum += $F[4]; END{ printf"%.f \n",$sum }'
3690

-ne 옵션을 이용한 현재 디랙토리의 파일 총 용량을 구하는 방법입니다.
이 옵션은  (split)[4] 사용하여 4번째 필드를 추출하고 $sum +=  .. 값을 $sum에 넣고 최종 값을 출력 하는 Perl one-liner입니다.
$ ls -al |perl -ne 'next if /^d/; $sum += (split)[4]; END{ printf"%.f \n",$sum/1024 }' 하면 kb -> mb로 변경 가능 합니다.

Cord Listing 3-2
 $ cat data2.log
1
2
3
4
5
6
7
8
9
10

$ perl -ne 'print if 2..5' data2.log
perl -ne 'print if ($. == 2 .. $. == 5)' data (소미님 ID어..)
2
3
4
5
-ne 옵션을 이용해서 특정 라인을 출력하는 방법입니다.
2~5 라인만 출력 됩니다.

Cord Listing 3-2
$ perl -i.old -ne 'print unless 2..5' data2.log
$ ls -al
-rw-r--r--  1 Administrator Mass   34 Apr  9 22:30 data2.log
-rw-r--r--  1 Administrator Mass   42 Apr  9 22:26 data2.log.old

$ cat data2.log
1
6
7
8
9
10
-i.old 옵션과 -ne 옵션을 사용하여 특정 라인을 없애는 방법입니다.
그럼 2~5 라인이 삭제 되고 나머지 부분만 출력 됩니다.

Cord Listing 3-3
 $ cat data.log
======================================
  DATE    과목       중간   기말
---------------------------------------
20090409 1.수학      86     12
20090409 2.영어      18     20
20090409 3.국어      67     20
20090409 4.미술      35     18
---------------------------------------
20090409 1.수학      39     39
20090409 2.국어      11     75
---------------------------------------
20090409 1.수학      13     64
20090409 2.영어      35     35
20090409 3.국어      77     68
20090409 4.미술      69     74
---------------------------------------

첫글자가 숫자로 8자리인 라인을 출력
$ perl -ne 'print if /^\d{8}/' data.log
20090409 1.수학      86     12
20090409 2.영어      18     20
20090409 3.국어      67     20
20090409 4.미술      35     18
20090409 1.수학      39     39
20090409 2.국어      11     75
20090409 1.수학      13     64
20090409 2.영어      35     35
20090409 3.국어      77     68
20090409 4.미술      69     74


수학 과목만 출력
$ perl -ne 'print if /1\.\W/' data.log
20090409 1.수학      86     12
20090409 1.수학      39     39
20090409 1.수학      13     64


중간고사에서(즉 3번째 필드) 80점 이상인 라인만 출력
$ perl -ane 'print if $F[2] > 80' data.log
$ perl -F'\s+' -ane 'print if $F[2] >= 80' data.log (소미님 ID어..)

20090409 1.수학      86     12

다음 과제..
각 과목별 총점 및 평균 값 구하기..
위치 변경 s/row/
column/g
ex)
수학 영어 국어 미술
32     23    32    23
23     23    23    23
현재 가장 해보고 싶은 부분........아자!!!!
-ne 옵션의 정말 광범위한 사용 방법 이고, 이보다 더 좋은 방법으로 원하는 값을 추출 할 수 있습니다.

첫글자가 숫자로 8자리인 라인을 출력
: if /^\d{8}/ 핵심부분은 이부분인데요. 처음 부분이 숫자로 된 8자리를 출력 하기 위해서 사용한 정규표현식입니다. \d [0-9] 같은의미를 가지고 있으며 0~9까지 숫자 한자를 의미 하고 {8}은 앞에 있는 숫자를 총 8번 반복 한다는 의미입니다.

수학 과목만 출력 : if /1\.\W/' 여전히 핵심은 이부분 입니다. 1그리고 \.(.)와일드카드로써 (.)을 문자로 바꿔 주고 \W [^a-zA-Z0-9]과 같은 의미를 가지고 있습니다. 즉 대문자도 숫자도 아닌 문자를 말하는 것입니다.
함정이 있을 수 있습니다. 예를 들면 /metachar 매타문자가 들어있다면 원하는 값이 나오지 않겠지만 현재 부분에서 불필요하게 /metachar을 사용할 필요는 없습니다.

중간고사에서(즉 3번째 필드) 80점 이상인 라인만 출력 : 제가 가장 고심한 부분이고 미소님의 도음으로 중요한 부분을 알 수가 있었습니다.  위에서 선언한 옵션보다 하나다 추가 되었습니다 그부분은 -a (split된 결과를 @F 배열에 사용) 옵션입니다. 배열을 사용하기 위해서 위와 같이 추가하고 if $F[2] > 80' 3번째 필드의 값 중 80이상인 라인을 출력 하는 부분이며, 미소님 처럼 -F'\s+' 이용하여 (스페이스, 탭, 개행)인 문자의 이상값을 패턴으로 잡고 if $F[2] >= 80' 식으로 출력 하면 앞서 말한 것 처럼 3번째 필드의 값을 출력 하게 됩니다. 중요한 부분은 awk -f' ' 처럼 $1, $2, $3로 주어지는 것이 아닌 $F[0], $F[1], $f[2]로 시작 합니다.

그럼 다음 이야기는 주말 당직이시간에.....................흐미 황금같은 주말을 ...
그래도 Perl이 있어 행복..하다.
내일은 꼭 해내야 하는데......................ㅎㅎ



참고 자료
================================================================================
             사이트                                                      이름
================================================================================
http://aero.springnote.com/                                                       (aero님)
http://aero.sarang.net/blog/                                                       (aero님)
http://www.unixguide.net/unix/perl_oneliners.shtml          (HOT PERL ONLINERS)
http://sial.org/howto/perl/one-liner/                               (Perl Argument Overview)
http://www.perl.com/pub/a/2004/08/09/commandline.html  (Perl Command-Line Options)
http://devfrog.egloos.com/191794                                              (devfrog님)
http://doc.perl.kr/twiki/bin/view/Wiki/HowToStartPerl                  (펄덕펄덕)
http://cafe.naver.com/perlstudy.cafe                                 (대한민국Perl커뮤니티)
================================================================================

 


Comments