[Perl] Syntax Summery

1. ~ 2. Source 참조


3. 변수와 기본 연산

다른 언어들과는 달리 변수형을 지정할 필요 없이 대입과 동시에 변수형이 결정된다.  변수는 $기호로 시작되며 배열의 경우 @, 조합배열(hash)은 %기호로 시작된다.  $bom = 123; 과 같이 $bom 변수에 123이라는 정수를 대입하게 되면 별도의 조치 없이 정수형을 갖게 된다.  변수간의 연산도 매우 자유롭다.  예를 들어 다음과 같은 경우 결과값은 정상적인 수치 연산결과인 100이 출력된다.

$bom = 49;   # 정수
$danvi = “51”;   # 문자열
print $bom + $danvi;  # 100 출력

perl 문법상 # 기호 이후부터는 주석으로 인식한다.  예상하듯이 Perl에서는 사칙연산에 +, -, *, / 기호가 이용되며 나머지(계수)에는 % 기호가 사용된다. 
문자열 연산자는 .(마침표, dot)를 사용하며, 연산방법 또한 앞에서와 같이 간단하다.

$bom = 100;  # 정수
$danvi = “200”;  # 문자열

print $bom . $danvi; 와 같이 문자열 연산자를 이용하면 “100200”이 출력되고 print $bom + $danvi; 와 같이 수치연산자를 이용하면 300이 출력된다.


4. 조건문

if (조건) { 참일 때; }
else { 거짓일 때; }

두 개 이상의 조건문은 elsif(“elseif”가 아님에 주의)를 이용하여 다음과 같이 구성할 수 있다.

if (조건) { 참일 때; }
elsif (조건) { 새로운 조건이 참일 때; }
elsif (조건) { 새로운 조건이 참일 때; }
. . . .
else { 모두 거짓일 때; }

조건판별을 위한 연산자로서 ==(eq)는 일치, !=(ne)는 불일치로 사용되며 <, >, <=, >= 등의 기호를 사용할 수 있다.  또한 논리연산자로서 &&(and), ||(or), !(not)도 사용할 수 있다.(기호와 영문 모두 사용할 수 있다.)

$bom = 5;
if ($bom < 10 and $bom > 3) {
  print “10보다는 작고 3보다는 크다. \n”; }

소스를 실행해보면 당연히 “10보다는 작고 3보다는 크다.”가 출력될 것이다.

if와는 반대로 사용되는 조건문으로는 unless가 있다.

unless (조건) { 거짓일 때; }
else { 참일 때; }


5. 반복문

while (조건) { 조건이 참인 동안 실행; }
until (조건) { 조건이 거짓인 동안 실행; }
무한루프를 원치 않는다면 당연히 중괄호({})를 실행하는 동안 조건과 관련한 값이 변화되어야 할 것이다.

$bom = 1;
while($bom <= 10) {
   print $bom, “\n”;
   $bom++; }

초기의 $bom의 값은 1이었고 해당 값이 10보다 작기 때문에 while문의 조건에 일치하므로 중괄호({}) 가 실행된다.  중괄호로 처리방향이 넘겨진 후 print 문에 따라 $bom의 값인 1이 출력된다. 만약 $bom++; 와 같이 $bom 값을 변화시켜주지 않는다면 $bom 값은 영원히 1일 것이므로 무한루프가 되어버릴 것이다. $bom++ 는 자동증가를 뜻하는 것으로서 원래의 $bom 값에 1을 가산한 후 다시 $bom에 값을 저장하게 되는 것이다. $bom– 는 그 반대이다. 루프를 한번 돌게되면 $bom 값은 2가 되고 한번씩 더 돌 때마다 3, 4, 5, 6, 7, 8, 9, 10이 된다.  $bom 값이 10일 경우 10을 출력하고 $bom++ 에 따라 $bom 값이 11이 되면서 while문의 조건에 맞지 않아 루프는 결국 종료된다.

또다른 반복문으로는 for문이 있다.

for (초기값; 조건; 변화값) { 조건이 참인 동안 실행; }

다음 소스는 앞서 설명한 while문의 예제와 동일한 결과를 보이게 된다.

for ($bom = 1; $bom <= 10; $bom++) {
   print $bom, “\n”; }

반복문중에는 foreach문도 있으나 배열과 관련하여 주로 사용되므로 설명을 뒤로 미루기로 하겠다.


6. 파일 핸들링

파일을 읽거나 저장하기 위해서는 파일을 열어야하며 일반적으로 다음과 같은 규칙에 의해 사용되어진다.

open(파일핸들, “[조작방법] 파일명”);

‘파일핸들’은 사용자의 식별을 용이하게 하기 위해 임의로 지정하여 사용한다. ‘조작방법’에는 읽기전용(< 또는 생략), 쓰기(>), 덧붙이기(>>) 등이 있다.

open(FILE, “>bom”);
  print FILE “Way\n”;
close(FILE);

분석해보면 다음과 같다.

open(FILE, “>bom”);

bom이라는 파일명으로 파일을 쓰기모드로 열되 파일핸들은 FILE로 지정한다.

print FILE “Way\n”;

FILE이라는 파일핸들(실제로는 bom이라는 파일)에 “Way\n”라는 문자열을 기록한다.

close(FILE);

FILE 이라는 핸들의 파일을 닫는다.  조작이 끝나는 즉시 닫는 게 바람직하다.

앞에서 알 수 있듯이 파일핸들을 사용함으로 해서 특정 파일에 print(기록)하고, 손쉽게 파일을 닫을 수 있게 된다.
소스가 실행되게 되면 bom이라는 파일이 생성되어지고 파일에는 Way라는 내용이 들어가게 될 것이다.
쓰기모드일 경우 이미 동일한 파일이 존재하면 내용을 덮어쓰게 되므로 종전내용을 잃게 된다. 하지만 덧붙이기(>>)모드로 파일을 열게 되면 종전내용의 하단에 새로운 내용이 추가된다.(대부분의 log파일 저장방식과 동일하다.)

이제 다음과 같은 소스를 작성하여 실행해보자.

open(FILE, “>>bom”);
  print FILE “Way2\n”;
close(FILE);

특별한 문제가 없는 한 bom이라는 파일내용은 다음과 같을 것이다.

$ cat bom
Way
Way2
$

저장하는 방법을 알았으니 이제 읽어 오는 방법을 알아보자.
open(FILE, “bom”);
  $line1 = <FILE>;
  $line2 = <FILE>;
close(FILE);

<FILE>이 어떤 기능을 하는지 궁금할 것이다.  <FILE>에서 FILE은 앞에서와 마찬가지로 파일핸들이며 <>(‘줄입력 연산자’라고도 한다.)로 묶이므로 해서 한 줄을 읽어 온다는 뜻이다.

$line1= <FILE>;
bom파일의 첫 번째 줄 내용을 $line1 이라는 변수에 저장(대입)한다.

$line2 = <FILE>;
한번 더 <FILE>을 사용하였으므로 두 번째 줄을 읽어 $line2에 저장하는 것이다.  그런데 모든 파일의 내용을 하나의 변수에 넣어 조작하고자 한다면 몇 줄인지 알 수 없기 때문에 앞의 방법보다는 다음과 같이 while문을 이용하는 것이 편리하다.

open(FILE, “bom”);
  while($line = <FILE>) {
        $all_line = $all_line . $line; }
close(FILE);

약간 복잡하게 느껴질 수도 있을 것이다.  첫줄과 마지막 줄은 설명이 필요 없을 듯 하여 가운데부분만 설명하도록 하겠다.  while문은 참일 경우 바로 뒤에 위치한 중괄호({})가 실행된다.  Perl에서는 아무런 값이 없을 경우 ‘거짓’을 돌려주므로 bom 이라는 파일을 모두 읽어오고 나면 while 루프가 종료되는 것이다.  약간 더 설명을 덧붙이자면, $line = <FILE> 이 참일 경우(읽어올 줄이 있을 경우는 참이 된다.) $line 변수에 읽어온 줄의 내용을 저장하고 문자열연산자(.)에 의해 $all_line 변수에 추가되며, 파일 끝까지 읽고 나면 읽어올 줄이 없어 거짓을 리턴 하므로 while 루프가 종료되는 것이다.

다음과 같이 간단히 나타낼 수도 있다.

open(FILE, “bom”);
  while(<FILE>) { $all_line .= $_; }
close(FILE);

$all_line .= $_ 부분은 $all_line = $all_line . $_와 동일한 결과를 보인다.

이제 특정파일의 내용을 읽어 변수에 저장하였으며 이로써 조작이 가능하게 되었다.

파일을 열거나 조작하고자 할 때 발생할 수 있는 오류를 미리 예방하고 파일(또는 디렉토리)에 관한 정보를 얻어 활용하기 위해 Perl은 다양한 파일테스트 연산자를 제공한다.

주요 연산자는 다음과 같다.

 

– e

  존재 여부

– r

  읽기 가능 여부

– w

  쓰기 가능 여부

– x

  실행 가능 여부

– d

  디렉토리 여부

– T

  텍스트파일 여부

– B

  이진파일(binary)  여부

– s

  파일크기

 

if (-e “bom”) { print “파일 있음\n”; }
else { print “파일 없음\n”; }

print “bom 파일의 크기는 “, -s “bom”, “ byte입니다.\n”;


7. 함수

구조적인 프로그램을 위해, 특히 빈번히 사용되는 특정 기능이나 처리절차를 하나의 함수로 생성하여 활용할 수 있다.

함수는 다음과 같이 구성되며 &함수명과 같이 호출한다. 함수는 중괄호({})로 묶이며 함수영역 내외를 불문하고 사용되어지는 문법은 동일하다.

sub 함수명 { 처리내용; }

앞서 설명했던 for문을 이용해 함수를 적용해보겠다.

for ($bom = 1; $bom <= 10; $bom++) {
   print $bom, “\n”;
   &job; }

sub job { print “===============\n”; }

소스를 실행해보면 1부터 10까지 출력되는 과정중 숫자 사이사이에 구분선이 그어질 것이다.  이런 용도의 함수는 작업을 좀더 간결히 하는 정도의 효과밖에 기대할 수 없지만, 다음과 같은 경우 호출시 &함수명(“넘길값”)과 같이 인자를 넘기고 호출된 함수에서는 넘겨받은 인자를 계산(처리)하여 결과를 리턴하게되는 완전한 함수의 형태를 띄게 된다.

for ($bom = 1; $bom <= 10; $bom++) {
   $danvi = &job($bom);
   # job 함수로 $bom이라는 변수값을 넘기고,
   # 돌려 받은 처리결과를 $danvi 변수에
   # 저장한다.
   print $danvi, “\n”; }

sub job {
  ($input) = @_;   # 값을 넘겨받는다.
  $output = $input * 10;  # 계산한다.
  return $output; }  # 결과를 돌려준다.

소스를 실행해보면 10, 20, 30, … 과 같이 $bom 값에 10을 곱한 값이 순서대로 출력된다.


8. 배열

여러 개의 값들을 하나의 변수에 저장하여 활용하기 위해 배열(array)과 조합배열(hash)이 지원된다.  둘의 차이점은 인덱스(index)가 숫자인가 그렇지 않은가 이다.

배열에 값들을 직접 대입하는 방법은 괄호를 이용하여 다음과 같이한다.
@way = (1, 2, 3, 4, 5);

배열대입은 다음과 같이 개별적으로도 가능하다.
$way[0] = 1;
$way[1] = 2;
$way[2] = 3;
$way[3] = 4;
$way[4] = 5;

배열을 일반변수형태로 추출하기 위해서는 다음과 같이 사용한다.
$way[배열번호]

첫 번째 값의 배열번호는 0이다.  따라서 $way[0]에는 1이, $way[1]에는 2가 저장되어 있는 것이다.

배열에서 값을 추출하여 또 다른 변수에 저장해보자.
$bom1 = $way[0];
$bom2 = $way[1];
$bom3 = $way[2];
$bom4 = $way[3];
$bom5 = $way[4];

또 다른 방법으로는 다음과 같은 방법도 존재한다.
배열에 직접 대입하던 것과는 반대이다.
($bom1, $bom2, $bom3, $bom4, $bom5) = @way;

조합배열은 %기호를 사용하며 숫자인덱스 대신 임의의 문자열(key)을 인덱스로 갖는다.  따라서 저장된 순서는 그다지 큰 의미가 없다.

%way = (“빨강” => “red”,
             “파랑” => “blue”,
             “검정” => “black”);

앞서 설명한 배열과 동일한 방법으로 대입하였지만 주의 깊게 관찰할 부분은 => 기호를 이용해서 key와 value로 구성된다는 것이다.

마찬가지로 $way{‘빨강’} = “red”; 와 같은 방식으로 개별적인 저장도 가능하다.

자료를 추출하기 위해서는 다음과 같이 사용하면 된다.

$way{key}

$way{‘빨강’} 에는 “red”가, $way{‘파랑’}에는 “blue”가 저장되어 있다.

보통 => 기호 대신 ,(comma)를 사용하기도 하지만 가독성을 높이기 위해 => 기호를 사용하는 것이 바람직하다.

print “파랑색은 영문으로 $way{‘파랑’}입니다.\n”;

소스가 실행되면 “파랑색은 영문으로 blue입니다.”가 출력될 것이다.
조합배열은 keys와 values를 이용해 인덱스나 값만을 추출해낼 수 있다.
print keys %way
소스가 실행되면 “빨강파랑검정” 등과 같이 출력된다.

이제 앞에서 설명을 미뤘던 foreach문에 대해 알아보자.

foreach 추출값 (배열 또는 목록) { 실행영역; }

배열값을 하나씩 추출하고 그때마다 중괄호로 묶인 실행영역을 거치게 된다. 배열의 모든 원소가 추출되고 나면 루프는 종료된다.

@bom = (“봄”, “여름”, “가을”, “겨울”);
foreach $danvi (@bom) {
  $count ++;
  print “$count, $danvi\n”; }

소스를 실행하면 다음과 같이 출력될 것이다.

1, 봄
2, 여름
3, 가을
4, 겨울

foreach문은 다음과 같이 사용할 수도 있다.  결과는 앞의 결과와 동일하다.

foreach $danvi (“봄”,”여름”,”가을”,”겨울”) {
  $count ++;
  print “$count, $danvi\n”; }

배열은 @way = (); 또는 %way = (); 와 같이 초기화할 수 있다.

배열에 원소를 추가하고자 할 경우 push를 이용한다.
push(배열명, 추가할 값);

@way = (1, 2, 3, 4, 5);
push(@way, 6);

@way 에는 6이라는 원소가 추가된다.


9. 문자열 처리

Perl은 문자열 처리에 상당한 능력을 과시하고 있다.

“ ”기호로 묶인 상태에서 변수를 직접 사용할 수 있다.
$way = “CDE”;
$way1 = “AB$way”;  # ABCDE

특정 문자를 지정한 수량만큼 복제하기 위해 x 라는 특수한 연산자를 이용한다.  구분선 출력이나 열을 맞추기 위한 공백 등에 자주 사용된다.
$way2 = “=” x 10;   # ==========

문자열중 일부분을 추출하는 방법은 다음과 같다.  시작위치는 0부터이다.

substr(변수, 시작위치, 글자수);

$way 라는 변수의 값중 첫 번째부터 2글자를 추출하여 $way3에 저장하는 방법은 다음과 같다.
$way3 = substr($way, 0, 2);   # CD

문자열 중에서 특정문자의 존재여부를 파악하는 방법은 다음과 같다.  실행결과 “있음”이 출력된다.

$way = “봄 여름 가을 겨울”;
if($way =~ /봄/) { print “있음\n”; }
else { print “없음\n”; }

문자열을 치환(substitution)하려면 다음과 같이 하면 된다.  실행결과 “이것이 사랑일까?”가 출력된다.

$way = “이것이 우정일까?”;
$way =~ s/우정/사랑/;
print “$way\n”;


10. 시스템 명령

`(역따옴표)기호를 이용할 경우 원하는 시스템 명령을 실행할 수 있으며 실행결과를 얻어와 활용할 수 있다.

$way = `ls -al`;
print $way;

이렇게 할 경우 shell에서와 마찬가지로 ls 명령결과가 출력된다.

$bom = `w`;
@user = (“way”, “lawwal”, “danvi”);
foreach $user_id (@user) { &login_check($user_id); }

sub login_check {
 ($id) = @_;
 if ($bom =~ /$id/) { print “$id : On-Line\n”; }
  else { print “$id : Off-Line\n”; }
}

필자가 사용중인 서버에서 소스를 실행한 결과 다음과 같이 출력되었다.

way : On-Line
lawwal : On-Line
danvi : Off-Line

만약 결과를 얻어올 필요가 없고 명령에 따라 부수적인 작업을 해야 한다면 system이나 exec를 사용한다.  exec의 경우 실행중인 Perl 프로그램은 종료되고 지정된 명령어가 실행된다는 차이점이 있다.

print “top 명령을 실행할까요? [Y/n] “;
$input = <STDIN>;
if ($input =~ /y/i) { system(“top”); }
else { print “취소되었습니다.\n”; }

줄입력연산자인 <> 사이에 STDIN(표준입력)이 들어가게 되면, 키보드로부터 값을 입력받는다. 입력된 값에 Y 또는 y가 존재하는 경우(i 옵션은 대소문자를 구별하지 않는다.) top 명령을 실행하도록 한다.

글의 문제가 있다면 댓글을 달아 주세요.

This site uses Akismet to reduce spam. Learn how your comment data is processed.