egrep

■ egrep 메타문자 요약

 

한 개의 문자에 매치시키기 위한 아이템

.

임의의 한 문자에 매치됨

ex) egrep?'2005.01.05'?file

2005, 임의의 한 글자, 01, 임의의 한 글자, 05에 매치

<2005/01/05, 2005-01-05, 2005.01.05>

[...]

문자클래스

열거된 임의의 문자에 대응됨

ex) egrep?'gr[ea]y'?file

g, r, e(or)a, y에 매치 <grey, gray>

[^...]

부정형 문자클래스

열거되지 않은 임의의 문자에 매치

ex) egrep?'pu[^t]'?file

p, u 뒤에 t가 오지 않는 행만 매치

\char

이스케이프 처리된 문자

char이 메타문제이거나 이스케이프 처리된 내용에 별도의 특별한 의미가 없다면 char문자에 매치 또는 새로운 메타문자를 정의함

ex) egrep?'\$[0-9]+'?file

행의 마지막을 의미하는 $의 의미를 그냥 돈의 단위인 $로 매치시킴 <$40>

 

뒤에 붙어서 '숫자를 세는' 역할을 하는 아이템

?

물음표

한번 나올 수 있지만 없어도 됨

ex) egrep?'html?'?file

h, t, m 뒤에 l이 나올 수도 있고 나오지 않아도 되는 행에 매치 <html, htm>

*

별표

반복회수에 제한이 없으며 아예 없어도 됨

ex)

egrep?-i?'<hr(?+size?*=?*[0-9]+)??*>?file

?이 한번이 나와도 되고 아니면 나오지 않아도 됨 즉 <hr size = 14 > (or) <hr size=14> 등의 스크립트에 매치

+

플러스

적어도 하나 있어야 되며 숫자에 제한이 없음

ex) 

egrep?-i?'<hr(?+size?*=?*[0-9]+)??*>?file

?이 한번 이상 나오는 경우에 적용됨 즉 htm 스크립트에서는 절대로 hrsize라고 붙여쓰지 않음을 말함 또, [0-9]는 숫자 하나에 대응하지만 숫자가 하나이상 나올 수 있음을 의미

min,max

주어진 범위

최소값과 최대값 사이에서 회수가 제한됨

 

위치에 매치되는 아이템

^

캐럿

행 시작되는 위치에 매치됨

ex) egrep?'^cat'?file

c, a, t으로 시작하는 행만 매치

$

달러

행 끝나는 위치에 매치됨

ex) egrep?'cat$'?file

c, a, t으로 끝나는 행만 매치

\<

단어 앞경계

단어의 시작 위치에 매치됨

ex) egrep?'\<cat'?file

c, a, t으로 시작하는 단어만 매치

\>

단어 뒤경계

단어의 끝 위치에 매치됨

ex) egrep?'cat\>'?file

c, a, t으로 끝나는 단어만 매치

 

기타

|

선택(or)

"|"로 분리되는 표현식 중 하나에 매치됨

ex) egrep?-i?'^(from|to)'?file

f, r, o, m이나 t, o로 시작하는 행에 매치

(...)

괄호

① 선택의 범위를 제한하거나 ② 수량자가 적용되는 그룹을 지정하거나 ③ 백레퍼런스를 쓸 때 위치를 지정하기 위한 메타 문자

ex) egrep?-i?'^(from|to)'?file

^의 선택범위를 제한하기 위해서 사용됨

\1, \2

백레퍼런스

앞에서 첫 번째, 두 번째,... 등의 괄호 안에서 매치된 텍스트에 매치됨

ex) egrep?-i?'\<([a-z]+)?+\1\>'?file

\1은 ([a-z]+)에 매치 <옆의 예는 중복단어 체크 매치시키는 표현식>



■ 앞의 표를 이해하는데 유의사항

 

  1. 이탤릭체로 적은 것은 egrep의 버전에 따라서 적용을 시킬 수 있는 경우가 있고 없는 경우가 있으니 주의해서 사용하기 바란다.


  2. ?는 공백의 의미를 사용했다. 이해하는데 무리가 없을 것이다.



■ 생각하는 방식을 바꾸자

ex> egrep 'cat' file

cat이라는 말에 매치되는 행을 찾는 것이 아니라 c 다음에 a 다음에 t가 나오는 행과 매치시키는 것이라고 이해하는 것이 정규표현식을 이해하는 첫걸음이다. 그리고 공백문자를 일반적인 a, b라는 문자와 똑같이 취급을 해야 한다. 공백문자는 컴퓨터는 특별한 무언가로 여기지 않는다.



■ 정규표현식은 언어다. 우리가 어떤 언어를 배우던지 자꾸 써보고 연습해 보는 것이 중요하듯이 정규표현식도 마찬가지다. 그래서 다양한 방법으로 표현된 정규표현식을 익히는 것이 중요하다.



■ grep에서 매칭을 진행하기 전에 일반적으로 \n인 줄바꿈 문자를 잘라내고 진행한다. 그래서 vi 편집기에서 찾을 수 있는 \n은 grep 에서는 찾을 수 없다.



■ 어떤 문자가 메타문자인지 아닌지는 정규표현식에서 문자가 있는 위치가 결정한다. 예를 들어서 *는 메타문자이지만 \* 인 경우는 escape된 경우이므로 메타문자가 아니다. 또 ^의 경우는 행의 제일 앞을 뜻하나 [^...] 의 경우에서는 ...에 매치되는 문자를 제외한 모든 문자에 매치시킨다. 한 가지의 예를 더 들어보자. -의 경우는 [a-z] 안에 있을 경우는 범위를 나타내지만 []밖에 있을 때는 그냥 -문자에 대치된다.




■ 지나치게 자세하게 찾으려는 표현식은 실용성을 떨어뜨린다.

  우리가 보통 날짜를 나타날 때 2005/01/05 또는 2005.01.05 또는 2005-01-05으로 나타내는데 그래서 우리는 위의 세 가지의 경우를 매치시키기 위해서 다음과 같은 정규표현식을 사용할 것이다.  ex> egrep '2005[./-]01[./-]05' file  그렇게 한다면 우리는 정확히 위의 세 가지 표현에 정확히 매치시킬 수 있지만 다소 타이핑의 수가 많아지게 된다. 그래서 우리는 다음과 같은 차선책을 택할 수 있다. ex> egrep '2005.01.05' file  경제적으로 찾을 수 있다. 하지만 이 표현식의 경우는 다음과 같은 위험이 따른다. 만약 2005901?05345 라는 일정한 배열의 숫자가 있다면 이 행도 찾는 결과를 가져온다. 따라서 우리는 경우에 따라서 정확성과 경제성 사이에서 적절하게 선택을 할 필요가 있다.



■ 위의 표현식이 모든 프로그램이나 편집기에 적용된다는 생각은 하지 말도록 부탁한다. 다른 프로그램에서는 좀 더 복잡한 형태로 정의된다. 다른 프로그램에서 정규표현식을 사용할 경우는 반드시 실험적으로 사용하고 난 뒤에 사용하거나 reference를 참고해서 사용해야 한다.



■ 문자클래스[]는 정규표현식 언어와 전혀 상관없이 별도의 메타문자를 사용



■ 이스케이프 처리되는 경우는 다음의 세 가지의 경우로 나눌 수 있다.


  1.  뒤에 메타문자를 사용하면 그 문자 자체가 가지는 형태로 매치된다. 예를 들어서 \* 라고 쓰면 스크립트 상에 있는  * 에 매치된다.


  2.  뒤에 메타문자가 아닌 문자를 쓰면 언어(language)에 따라서 다른 의미를 가지는 메타문자가 된다. 예를 들어 \< 이면 단어의 시작을 의미하는 메타문자가 된다.


  3.  뒤에 일반적인 문자가 오면  의 의미는 없는 것으로 치부해도 된다. 하지만 \1 , 의 경우는 백레퍼런스로 사용된다.



awk

■ awk란

  ? awk는 두 가지 측면을 가지고 있다. 하나는 단순한 Text 편집기로서의 측면과 좀 더 복잡한 연산을 수행하는 프로그램의 측면으로 나눌 수 있다. awk 하나만 잘 해도 웬만한 정도의 C program을 대신할 수 있을 정도의 힘을 가질 수 있다. (C program과 문법이 비슷하다.) 본론으로 들어가기 앞서는 왜 awk가 의미하는 것이 무언인지 알아야 하지 않을까. awk 는 Aho, Weinberger, and Kernighan 이 세 분의 initial을 따서 이름한 것이다. 그럼 본론으로 들어가서......



■ awk 둘러보기

  ? 다음은 예제 파일들이다.

    (파일명 : exe4.txt)

    

  gold     1    1986  USA                 American Eagle

  gold     1    1908  Austria-Hungary     Franz Josef 100 Korona

  silver  10    1981  USA                 ingot

  gold     1    1984  Switzerland         ingot

  gold     1    1979  RSA                 Krugerrand

  gold     0.5  1981  RSA                 Krugerrand

  gold     0.1  1986  PRC                 Panda

  silver   1    1986  USA                 Liberty dollar

  gold     0.25 1986  USA                 Liberty 5-dollar piece

  silver   0.5  1986  USA                 Liberty 50-cent piece

  silver   1    1987  USA                 Constitution dollar

  gold     0.25 1987  USA                 Constitution 5-dollar piece

    (파일명 : exe5.txt)

    

12;466;125;567;0.435

35;366;454;422;0.4565

35;36;45;42;0.45

34;45;235;236;0.454

567;55;233;446;0.56

34;0.53

    ex1) awk '/gold/' exe4.txt

      gold라는 문자를 가진 행을 출력한다.

    ex2) awk '/gold/ {print $5,$6,$7,$8}' exe4.txt

      gold라는 문자를 가진 행중에서 5, 6, 7, 8 열 만 출력해 준다.




    ex3) awk '{if ($3 < 1980) print $3, "    ",$5,$6,$7,$8}' exe4.txt

      3번째 열이 1980보다 작은 행중에서 3, 5, 6, 7, 8열만 출력해 준다. (간격을 ??     ?? 벌려서 만큼 출력한다.

    ex4) awk '/gold/ {ounce+=$2 END print "sum = "ounce}' exe4.txt

      gold라는 문자를 가진 행에서 두 번째 열을 더한 값을 ounce에 저장해서 그 값을 sum = 과 함께 화면에 출력을 해 준다.



■ awk 문법


  1. TEXT 편집문으로서의 awk문법

     

문법 : awk [-F<ch>] (pgm] | -f <pgm_file> [<vars>] [- | <data_file>]

ch : field separator character (필드 구분 문자)

pgm : awk command-line program (awk 명령문)

pdm_file : file containing an awk program (awk program이 있는 파일)

vars : awk variable initialization (awk 변수 초기화)

data file : input data file (입력하는 파일)


  2. PROGRAM으로서의 awk 문법

     

#!/bin/awk

BEGIN

<search pattern 1>

<search pattern 2>

<awk program syntax>

END




■ 검색 패턴 (search pattern)

  

/The/

The를 포함하는 행을 찾아준다.

/^The/

첫 글자가 T로 시작하는 것 중에서 다음 문자가 he가 나오는 행을 찾아준다

/The$/

T h e로 끝나는 문자가 있는 행을 찾아준다.

/$/

$가 있는 모든 행을 찾아준다

/[Tt]he/

The 나 the가 있는 행을 모두 찾아준다.

/[a-z]/

a부터 z까지 한 문자가 있는 행을 찾아준다

/[a-zA-Z0-9]/

다 알죠??

/wh./

wh와 그 다음의 임의의 한 문자와 대응한다.(why, who wh2 등등)

/^[+-]?[0-9]+$/

+or -를 가지고 있거나 없는 거나(++ -- +-는 매치되지 않음) 그 다음은 숫자가 하나이상 나오는 것인데 단어가 숫자로 끝나는 것에 매치한다.

/(^Korea)|(^China)

Korea 나 China에 매치된다.



■ 내부변수

  

FILENAME

현재 입력한 파일명

FS

필드 구분자 (초기값 0)

NF

필드의 개수

NR

현재 파일의 행 번호

OFS 

output의 field separator

$0

전체 입력 파일의 필드



■ 유용한 명령들

  ex1) awk -F ";" '{print NR,$1,$2,$3,$4,$5}' exe5.txt

    필드 구분 연산자를 공백에서 ;로 바꾸어 줌으로써 awk를 연산하고 있다.

  ex2) awk '{if (NR >2) print $0}' exe5.txt

    행 수가 3이상인 행만 출력한다.




  ex3) awk '{if (NF >2) print $0}' exe5.txt

    열 수가 3이상인 행만 출력한다.

  ex4) awk '{if (length($0) >10) print FILENAME,$0}' exe5.txt

    행의 단어 수가 11이상인 행만 출력한다.

  ex5) awk '{if (length($0) >10) printf("line %2d is %5.3f %6.2f %5.3f, %5.3f %5.4f ", NR, $1,$2,$3,$4,$5)}' exe5.txt

    printf 문의 형태가 C program과 일치하는 것을 알 수 있다. 우리는 쉽게 파일에 나오는 수들의 자리 수들을 쉽게 조절할 수 있다.

  ex6) awk '{print system(ls),FILENAME,$0}' exe5.txt

    system()은 UNIX 명령문을 처리하게 해 준다. 그리고 그 처리한 결과가 정상적으로 실행이 되었다면 그 결과로써 0을 리턴해 준다. 만약 실패하였다면 다른 값을 줄 것이다.

  ex7) awk '{print toupper($1), $2, $3}' exe4.txt

    toupper()은 괄호 안에 있는 문자를 대문자로 변환을 시켜서 출력을 시켜준다.

  ex8) awk 'print {tolower($1), $2, $3}' exe4.txt

    toupper()은 괄호 안에 있는 문자를 소문자로 변환을 시켜서 출력을 시켜준다.

  ex9) awk -F ";" '{print sqrt($1), $2, $3}' exe5.txt

    $1을 제곱근 해 준 값이 출력된다. sqrt뿐만 아니라 다음의 함수들도 존재한다. 효과적으로 이용하시길... atan2(y,x) : 아크 탄젠트 y/x를 출력, cos(x), sin(x), exp(x), log(x), int(x)

  ex10) awk '/silver/ {++x END print x}' exe4.txt

    silver와 일치하는 패턴의 줄 수를 구해 주는 것이다. 이것과 똑같은 결과를 얻기 위한 명령으로는 grep ??silver?? exe4.txt | wc -l 이 있다.

  ex11) awk '$1~/silver/ {print $0}' exe4.txt

    $1에서 silver에 매치되는 행들만 출력해준다. 이 명령은 좀 더 유연한 명령을 실행시켜 명령의 완성도를 높인다고 볼 수 있다.

  ex12) awk '{gsub("from","to");print}' exe2.txt

    from을 to로 모두 치환해서 화면에 출력해 준다.

  ex13) awk -F";" '{if(($1>30) &&($2>100)) print $0}' exe5.txt

    첫 번째 열이 30보다 크고 그리고 두 번째 열이 100보다 큰 것을 출력해준다.





■ awk 프로그램 예제


  1. 합계 구하기

    #!/bin/awk

    #파일명 : sum.awk

    #첫 번째와 두 번째 열을 읽어 들여서 각각의 산술평균을 구하는 awk 프로그램

    #사용법 : awk -f sum.awk filename

     

 

BEGIN 

x_sum = 0;

y_sum = 0;

print "Xcen_image";

print "Ycen_image";

 

x_sum +=$1;

y_sum +=$2;

n++

x_average = x_sum/n ;

y_average = y_sum/n ;

 

END print "x_sum :" x_sum ;

printf("%d ", x_average);

 

print "y_sum :" y_sum;

print "y_average :" y_average;

 


  2. 중복되는 행 출력하지 않게 하기

    #!/bin/awk

    #파일명 : uniq.awk

    #첫 번째 열이 같은 행은 출력하지 않고 첫 번째 열이 다른 것이 나오는 행을 출력한다.

    #사용법 : awk -f uniq.awk filename

     

BEGIN  FS = " "

 

if (var != $1 && NR != 1)

print line

var = $1

line = $0

 

END print line



  3. 첫 번째 열을 인자로 사용하는 배열을 사용하여 같은 인자를 가지는 배열일 경우에는 그 합을 구해주기

    #!/bin/awk

    #파일명 : array.awk

    #사용법 : awk -f array.awk filename

     

 

BEGIN  FS=";"

OFS=":"

      

    total[$1] += $2;

        if( lastcategory != $1)

    printf("lastcategory != $1 ");

            print $1;

            lastcategory = $1

        printf( "       ");

        print $1,$2;

      

END     printf(" "); print "TOTALS";

        for(category in total)

 

                printf("        ");

                print category, total[category];

 


이의 사항이 있거나 질문이 있으시면 이곳으로 이메일을 보내주세요 Webmaster

Copyright ⓒ 2005 All Rights Reserved by Hahn Yi

[출처] [리눅스 awk] awk|작성자 holyruby

'OS > LINUX' 카테고리의 다른 글

쉘스크립트 Example2  (0) 2011.05.14
쉘스크립트 example  (0) 2011.05.14
YUM 사용법  (0) 2011.05.13
vi 사용하기  (0) 2011.05.03
GNU screen  (0) 2011.04.23

[펌] [cyberuls.springnote.com]

 

php4에서는 단일 상속과 몇가지에 대한 지원밖에는 해주지 못했지만.. php5에서는 자바의 객체지향 모델을 가지고 옴으로써 여러가지를 지원해주게 됩니다.

 

  1. 상속

여전히 상속은 단일 상속만을 지원합니다.

하지만 interface 개념을 도입함으로써 여러가지로 작동하는 원리로 만들어줍니다. interface는 다중상속을 위해서 나온 것은 아닙니다. 그러니 다중상속 개념은 없다고 보는것이 맞겠지요...

 

2. 인터페이스  

     php5에서는 interface 개념을 지원합니다. interface는 다른 객체와 잘 부합할 수 있도록 객체의 표준을 마련하는 것이라 보면 쉽겠습니다.

 

3.  추상 클래스

    인터페이스와 비슷한 개념으로 추상클래스를 지원합니다. 하지만 추상클래스와 인터페이스의 용도는 좀 다르죠.. 일단 클래스이기 때문에 상속은 단일 상속밖에 할 수 없습니다. 그리고 추상메소드를 정의를 해야하고 abstract 라는 키워드를 써서 추상클래스임을 명시해야합니다. 일단 설계하는 클래스가 여러가지로 몇가지 기능을 빼고는 다 같은 방식으로 작동이 된다면 추상클래스는 아주 좋은 선택이 될 수도 있습니다.

 

  •  php5에서는 추상 클래스에서 인터페이스를 구현(implements) 하면 인터페이스에 속해 있는 메소드들은 무조건 실제 작동하는 메소드로 생성이 되어야 합니다. 하지만 자바에서는 인터페이스 메소드들도 그대로 추상메소드로 되어질 수 있습니다. 이것이 조금 번거로울 수도 있겠네요.

예를 들어서   java 는

interface A { public void a();}

abstract class B implements A { abstract public void a(); }

 

php는

 

interface A { public function a(); }

abstract class B implements A { public function a() { echo "aaa"; } }

 

위의 예제와 같이 java는 interface의 메소드(추상메소드이지요)는 추상클래스내에서 다시 추상메소드가 될 수 있지만 php는 반드시 구현되어야 하는 메소드가 되버립니다.

 

4.  오버로딩(Overloading), 오버라이딩 (Overriding)

오버로딩은 같은 클래스 내에서 이미 정의해 놓은 메소드를 같은 의미이지만 다른 매개변수를 사용 할 때 같은 이름의 메소드를 정의 할 수있게 해주는 것을 말합니다.

오버라이딩은 상속관계에서 같은 메소드이지만 다른 내용으로 만들고 싶을 때 메소드를 재정의 하는 것을 말합니다.

  php5 에서 사용하는 방법은 조금 신기합니다. ㅋㅋ

     일단 오버라이딩은 자동으로 됩니다... php에서는 같은 이름의 함수가 있으면 가장 마지막에 선언이 되어진 함수로 실행을 하기 때문에 오버라이딩은 자동으로 되게 되어있습니다. 그렇다면 오버로딩은 어떨까요?

 

     php5 에서는 몇가지 매직함수를 지원하는데요.. 그중에서 __call 이라는 놈이 재미난 놈입니다...

     이놈은 선언 되어지지 않은 메소드가 실행이 될때 실행되어지는 메소드 입니다.

 

     예를 들어서

 

     class AAA   {

          function run() {

 echo "뛰어";

          }

}

 

$a = new AAA();

$a->run();

 

   일반적으로는 이렇게 실행을 하는데요....

 

   $a->run_to("진호");

 

      이런식으로 선언되어지지 않은 메소드를 사용하면 __call 이 자동으로 불리어집니다. ㅋㅋ 오~~ 여기서 부터 재밌습니다.

      그럼 __call은 어떻게 쓰느냐... ㅋ

 

     class AAA   {

          function run() {

 echo "뛰어";

          }

 

function __call($func, $args) {

     echo "함수 : ", $func, ", 매개변수 리스트 ", implode(",", $args) ;

   }

}

    

      이런식으로 __call 은 메소드 이름과 매개변수 리스트를 배열로 받아들인다. ㅋㅋ  자 이간단한 개념을 가지고 살짝 재밌는 기능을 구상해 보자.

 

     요즘 웹프레임워크 중에 제일 잘 나가고 있는 루비의 일부 기능을 흉내내보겠당... 루비는 메타프로그래밍이 가능한 아주 유연한 언어이다.

    실행중에 클래스 메소드 자체를 마음대로 바꾸어 줄 수 있다. 그런 기능을 이용해서 레일스에서는 액티브 레코드에 여러가지 기능을 넣어두었다.

 

    예를 들어

 

  obj.find_by_name("진호")     --- name 필드가 진호인 것을 찾는다.

 

     여기서 주의깊게 봐야할 부분이 name 부분인데 이것은 필드 이름인데 언제 어디서든 바뀔 수가 있답니다. 그렇다면 메소드가 동적으로바뀐다는 말이되겠군요..

     어! 메소드가 동적으로 바뀌네 하면 php에서는 __call 을 떠올리세요. ㅋㅋ

 

    function __call($func, $args) {

       if (strpos($func, "find_by_") == 0) {

             // 자 이제 메소드에서 나머지 부분만 때어 볼까요?

            $arr = explode("find_by_", $func);

         $field = $arr[1];      // 이렇게 하면 필드 이름이 나오겠네요.. 오호~~

            $value = $args[0];   // 이렇게 하면 검색 하는 값이 나오겠네요. .오.. 정말..

 

           //  오 쉽게 select 구문이 되네요.. ㅋ

           $sql = "select * from 테이블 where {$field} = '{$value}' ";

 

           // 나머지는 상상에 맡길게요.. ㅋ

       }

    }

 

    제가 여기서 말하고자 하는 것은 php5 오면서 상당히 유연해졌다는 것입니다. 그리고 pecl에 있는 라이브러리 중에서는 실행시간 중에도 php의 메소드를 바꿔주는 메소드도 있습니다.. 즉 메타프로그래밍이 된다는 거죠.... ^^

 

    앞으로도 php는 발전 가능성이 너무 많네요.... ㅋ

 

5. 다형성

    다형성이라는 말은 여러가지로 해석이 될 수 있는데요,,,  하나의 자료형에 여러가지 다른 자료형을 넣을 수 있느냐는 것과 서로 유사한 클래스들을 하나의 인터페이스로서 제어 할 수 있느냐는 것도 다형성 중에 하나의 요소가 됩니다.   이것에 대해서는 php는 왕이죠.. 거의..  (필자가 생각하기에는.. ㅋㅋ )

 

    array  하나로 모든 것을 저장하고 내 뱉고 검색 할 수 있답니다.. 심지어는 array_multi_sort 라는 함수를 이용하면 db 에 있는 데이타를 가지고 와서 배열에 담아두고 그 자체로 다시 정렬 할 수 있습니다. 그래서 php는 기본적으로 다형성을 가지고 시작을 합니다. 모든 자료형은 동적으로 생성이 됩니다. 스크립트 언어들의 거의 기본적인 특징이죠... 그래서 좀 더 유연하고 쉽고 빠르게 프로그래밍을 배울 수 있답니다. 하지만 쉽다는 것이 곧 아무나 한다는 의미는 아니니 명심하세요...

 

6. 동적 바인딩

 동적 바인딩은  실행시간에 실제 그 객체의 메소드를 정확하게 찾아서 메소드를 실행 시키는 방법입니다. 이 말은 C++이나 자바에서 많이 접할 수 있는데요...

 C++이나 자바는 미리 클래스를 선언해주고 변수에 객체를 할당합니다. 그래서 그 클래스 변수에는 딱 정해진 자료형으로만 사용되어지는데요...

 그래서 인터페이스나 추상클래스를 두고 실제 움직이는 메소드에 대해서는 다른 클래스에 맡겨 두는 방식이 됩니다. 그렇게 되면 여러 클래스들이 인터페이스나 추상클래스 앞으로 모일 수가 있답니다. 즉 인터페이스와 추상클래스를 가지고 다른 클래스들을 공통적인 방법으로 실행하지만 실제 실행되는건 인터페이스나 추상클래스가 아닌 실제 그것을 구현한 클래스에 들어있는 메소드라는 것입니다.. 자기 자신을 아는 것이죠...

 

   하지만 php는 애초에 자료형을 지정해줄 필요가 없답니다. 그래서 지금 내가 할당되어진 객체 그 자체로 실행을 하기 때문에 언제든 동적 바인딩이 된다고 볼수가 있답니다. 그러니 좀 더 편하게 프로그래밍을 할 수 있답니다.


마법 메서드 (Magic Methods): __call(), __get(), __set(), __isset(), __unset()

이건 다들 아는 기능이다. 메서드 호출, 멤버 접근 등을 저 메서드를 통해서 속일 수 있다. 예를 들어 PHP에서는 원래 메서드 오버로딩이 안되는데, 이걸 이용하면 오버로딩을 흉내낼 수도 있다.

SPL

원래 확장으로 만들어져 PHP 5.2부터는 기본으로 포함하게 된 SPL은 엄청난 축복이다. 이름을 보면 짐작할 수 있듯, C++ STL의 반복자 개념에 영향을 받아 만든 라이브러리다(나도 STL을 좋아한다). 이것을 잘 이용하면 유사 배열 객체를 만들 수 있다.

Traversable

이 인터페이스를 구현하면 foreach문에 객체를 집어넣어서 배열처럼 돌릴 수 있다. Traversable은 유사 인터페이스고, 실제로는 Iterator 혹은 IteratorAggregate를 구현하면 된다. 전자는 반복자를 직접 구현하는 방식이고, 후자는 IteratorAggregate->getIterator() 메서드를 구현하여 반복자 객체를 위임하는 방식이다. 간단하게 배열처럼만 작동하는 객체를 의도한다면 후자가 좋고, 좀더 정교한 것을 원하면 직접 Iterator를 구현하는 것이 좋다.

Countable

이 인터페이스를 구현하면 count() 함수에 넣었을 때 배열처럼 원소 개수를 반환하게 할 수 있다.

ArrayAccess

정말 유용하다. 이거 모르는 사람이 매우 많은데, 첨자 연산자([])를 오버로드할 수 있다. 단순히 값을 반환하는 것 말고도 해당 키가 존재하는지 확인하는 것(isset($obj[$key])), 해당 키의 원소를 삭제하는 것(unset($obj[$key])), 원소를 덧붙이는 것($obj[] = $value), 해당 키의 원소 값을 수정하거나 추가하는 것($obj[$key] = $value)이 가능하다.

아, 중요한 것 하나. 배열과 달리 ArrayAccess를 구현한 객체는 키 값으로 스칼라 외에 배열이나 객체도 받을 수 있다.

가변 인자: func_get_args()

가변적인 갯수의 인자를 전달받을 때 사용한다. PHP는 함수 선언시에 명시한 시그너쳐에 맞지 않는 호출을 하면 오류를 내는데, 시그너쳐의 갯수보다 많은 인자를 받을 땐 오류를 내지 않는다. 이걸 이용하면 가변 인자를 받으면서 쉽게 오류 처리를 할 수 있다. 예를 들어 인자 갯수는 가변적이지만, 꼭 맨 처음의 인자 하나는 배열로 받아야 한다는 제약 사항이 있다면?

function get_array_and() {
    $args = func_get_args();
    if(!count($args) or !is_array($args[0]))
        throw new InvalidArgumentException('First parameter must be array');
    $array = $args[0];

위와 같이 할 수도 있지만, 아래처럼 하면 굳이 제약 사항을 검사하고 오류를 내는 코드를 직접 작성할 필요가 없다.

function get_array_and(array $array) {
    $args = func_get_args();

주의할 것이 있다. 이 함수의 호출은 항상 맨 첫 문장, 대입식을 제외한 가장 바깥 표현식이어야 한다. 그렇지 않으면 의도한대로 작동하지 않는다. 이유는 나도 모른다. 하지만 이 버그는 PHP쪽에서는 유명하다.

eval()

전달된 PHP 코드 문자열을 해당 문맥에서 실행한다. eval('echo 1234;')1234를 출력한다. 그렇지만 표현식을 받지는 않는다.

$expr = '123 + 456';
$value = eval($expr);

위와 같이 하면 문장이 세미콜론(;)으로 종결되지 않았다며 구문 오류가 난다. 표현식을 평가하고 싶다면 아래와 같이 써야 한다.

eval("\$value = ($expr);");

Reflection

PHP 5에서 추가된 리플렉션 기능을 사용하면 클래스의 멤버와 메서드 목록을 얻는다던가, 함수의 시그너쳐를 추적하는 등의 일을 할 수 있다. 인자에 타입 힌트가 있는지, 있다면 어떤 타입인지, 기본값이 있는지, 변수 이름이 무엇인지 등도 알 수 있다. 이런걸 이용하면 Python의 키워드 인자도 흉내낼 수 있을 것이다.

__toString()

이것도 마법 메서드의 하나인데, PHP 5에서 추가된 기능이다. 이 메서드를 정의한 객체는 echo문으로 출력할 때 __toString()이 반환한 문자열을 출력한다. Python의 __str__ 속성과 비슷한 용도이다. 그런데 이게 PHP 5.2 이후로는 substr() 같이 문자열을 받는 함수에 전달될 때 자동으로 해당 문자열로 캐스팅도 된다. 물론 명시적으로 (string) 캐스팅 연산자를 쓰는 것도 잘 된다.

trigger_error()

웬만하면 예외를 던지는 것이 좋지만, PHP 에러를 내야할 필요가 있을 때 이걸 사용한다.

debug_backtrace()

이 함수를 사용하면 호출 스택을 추적하는 것이 가능하다. eval()을 통하는 것과, include, require를 통한 것도 모두 추적할 수 있다. 대체 이 함수를 어디에 쓰겠느냐고 무심코 지나치면 안된다. 이 함수를 기억하고 있는 것만으로도, 종종 우연히 이 함수를 이용하여 좀더 우아한 DSEL을 달성할 때가 많다.

이 함수를 이용하는 대신 예외 객체를 생성하여 Exception->getTrace() 메서드로 받아내는 방법도 있다.

__FILE__ 상수

__FILE__ 상수의 값은 include, require 등과 무관하게 해당 상수는 현재 코드가 위치한 실제 파일 경로이다. 예를 들어 require_once dirname(__FILE__).'/file.php'과 같이 해당 소스 파일과 같은 위치에 있는 file.php를 불러올 수 있다. (저렇게 하지 않으면 include 호출의 맨 위쪽에 있는 파일에 상대한 경로로 인클루드를 시도한다.)

operator 확장

PHP에 기본적으로 포함되지는 않았지만, 매우 유용한 확장이다. 연산자 재정의를 가능하게 해준다. C++의 Boost.Spirit 라이브러리 같은 것을 보면 연산자 재정의가 얼마나 언어의 표현력을 높여주는지 알 수 있다. 자세한 것은 내가 예전에 정리해둔 문서를 참고하시라.

 

출처: http://blog.dahlia.pe.kr/?s=lexical


초보 관리자/DB 2009/01/29 11:24 by 비트센스
 
짬짬히 이런 저런 작업을 하면서 글을 쓰기 때문에,
실제 사용하는 것만 올립니다. 덕분에 글이 짧네요.

MSSQL에서 날짜 연산 방법입니다.

예. 어제 일자를 알고 싶다.
select getdate(), dateadd(d, -1, getdate())
쉽죠? ^^;;

연산 날짜 부분(datepart) 인지는 몇개 없습니다.

yy : 년
mm : 월
dy, y : dayofyear (먼지 잘 모르겠음)
d : 일
wk : 주
hh : 시
mi, n : 분
s : 초
ms : 밀리세컨드

declare @날자 datetime

set @날자='2008-01-01'

---현재월의 초일 --
SELECT dateadd(d,-day(@날자)+1,@날자)

---현재월의 말일 --
SELECT dateadd(d,-day(dateadd(m,1,@날자)), dateadd(m,1,@날자))

---전월의 초일 --
SELECT dateadd(m,-1, dateadd(d,-day(@날자)+1,@날자))

---전월의 말일 --
SELECT dateadd(d,-day(@날자),@날자)

== 또다른 매달말일 구하는 법
SELECT CONVERT(Char(8), DateAdd(day, -1, DateAdd(month, 1, @종료월 + '01')), 112)

'Database > SQL-Server' 카테고리의 다른 글

DBCC 명령어  (0) 2011.06.29
DBCC CHECKDB, CHECKTABLE (손상된 테이블 복구)  (0) 2011.06.27
[MSSQL] 날짜 연산 DATEADD  (0) 2011.05.13
MSSQL Date Type Convert  (0) 2011.05.13
[MSSQL - SELECT 와 INSERT 동시 처리]  (0) 2011.05.09
0 Feb 22 2006 4:26PM CONVERT(CHAR(19), DATETIME, 0)
1 02/22/06 CONVERT(CHAR(8), DATETIME, 1)
2 06.02.22 CONVERT(CHAR(8), DATETIME, 2)
3 22/02/06 CONVERT(CHAR(8), DATETIME, 3)
4 22.02.06 CONVERT(CHAR(8), DATETIME, 4)
5 22-02-06 CONVERT(CHAR(8), DATETIME, 5)
6 22 Feb 06 CONVERT(CHAR(9), DATETIME, 6)
7 Feb 22, 06 CONVERT(CHAR(10), DATETIME, 7)
8 16:26:08 CONVERT(CHAR(8), DATETIME, 8)
9 Feb 22 2006 4:26:08:020PM CONVERT(CHAR(26), DATETIME, 9)
10 02-22-06 CONVERT(CHAR(8), DATETIME, 10)
11 06/02/22 CONVERT(CHAR(8), DATETIME, 11)
12 060222 CONVERT(CHAR(6), DATETIME, 12)
13 22 Feb 2006 16:26:08:020 CONVERT(CHAR(24), DATETIME, 13)
14 16:26:08:037 CONVERT(CHAR(12), DATETIME, 14)
20 2006-02-22 16:26:08 CONVERT(CHAR(19), DATETIME, 20)
21 2006-02-22 16:26:08.037 CONVERT(CHAR(23), DATETIME, 21)
22 02/22/06 4:26:08 PM CONVERT(CHAR(20), DATETIME, 22)
23 2006-02-22 CONVERT(CHAR(10), DATETIME, 23)
24 16:26:08 CONVERT(CHAR(8), DATETIME, 24)
25 2006-02-22 16:26:08.037 CONVERT(CHAR(23), DATETIME, 25)
100 Feb 22 2006 4:26PM CONVERT(CHAR(19), DATETIME, 100)
101 02/22/2006 CONVERT(CHAR(10), DATETIME, 101)
102 2006.02.22 CONVERT(CHAR(10), DATETIME, 102)
103 22/02/2006 CONVERT(CHAR(10), DATETIME, 103)
104 22.02.2006 CONVERT(CHAR(10), DATETIME, 104)
105 22-02-2006 CONVERT(CHAR(10), DATETIME, 105)
106 22 Feb 2006 CONVERT(CHAR(11), DATETIME, 106)
107 Feb 22, 2006 CONVERT(CHAR(12), DATETIME, 107)
108 16:26:08 CONVERT(CHAR(8), DATETIME, 108)
109 Feb 22 2006 4:26:08:067PM CONVERT(CHAR(26), DATETIME, 109)
110 02-22-2006 CONVERT(CHAR(10), DATETIME, 110)
111 2006/02/22 CONVERT(CHAR(10), DATETIME, 111)
112 20060222 CONVERT(CHAR(8), DATETIME, 112)
113 22 Feb 2006 16:26:08:067 CONVERT(CHAR(24), DATETIME, 113)
114 16:26:08:067 CONVERT(CHAR(12), DATETIME, 114)
120 2006-02-22 16:26:08 CONVERT(CHAR(19), DATETIME, 120)
121 2006-02-22 16:26:08.080 CONVERT(CHAR(23), DATETIME, 121)
126 2006-02-22T16:26:08.080 CONVERT(CHAR(23), DATETIME, 126)
127 2006-02-22T16:26:08.080 CONVERT(CHAR(23), DATETIME, 127)
130 24 ???? 1427 4:26:08:080PM CONVERT(CHAR(32), DATETIME, 130)
131 24/01/1427 4:26:08:080PM CONVERT(CHAR(25), DATETIME, 131)

mysql

SELECT LAST_INSERT_ID();

php

@mysql_insert_id();

mssql

select @@identity 


출처: http://mwultong.blogspot.com/2007/05/php-cli-argc-argv.html


PHP CLI (Command Line Interface) 에서는, 다른 프로그램들처럼 실행시 옵션을 지정해 줄 수 있습니다.

$argc 에는 옵션의 개수가 자동으로 저장되어 있고, $argv 에는 실제 옵션들이 문자열로 저장되어 있습니다. 다만 0번째 옵션은, PHP 파일 자신의 이름이기에, $argc 에서 빼기 1을 해주어야 정확한 옵션 개수가 구해집니다.

다음 예제는 PHP 버전 5 이상에서만 실행됩니다.

$argc, $argv: 실행시 옵션 구하기/출력 예제


소스 파일명: example.php
#!/usr/bin/php
<?php

  if ($argc == 1) {
    fwrite(STDERR, "옵션 없이 실행하셨군요.\n\n");
    exit(1); // 운영체제에 에러코드 1을 반환하며 종료
  }


  echo "* 옵션 개수: " . ($argc - 1) . "\n\n\n";

  print_r($argv);


  // 일반 배열처럼 숫자를 첨자로 지정하면
  // 각 옵션에 접근할 수 있음
  echo "\n\n* 특정 옵션 출력: \$argv[1] = " . $argv[1] . "\n";

?>



실행 결과 화면:
D:\Z>php example.php
옵션 없이 실행하셨군요.

D:\Z>php example.php 111 222 333 뿡뿡이 똠방각하
* 옵션 개수: 5


Array
(
    [0] => example.php
    [1] => 111
    [2] => 222
    [3] => 333
    [4] => 뿡뿡이
    [5] => 똠방각하
)


* 특정 옵션 출력: $argv[1] = 111

D:\Z>example.php 111 222 333 뿡뿡이 똠방각하
옵션 없이 실행하셨군요.



D:\Z>


주의 사항: 위의 빨간 문자열 부분은 에러가 난 곳입니다. (편의상 빨갛게 표현했을 뿐 PHP 자체가 색깔을 출력한 것은 아님)

도스창 등에서 실행할 때, 파일명 앞에
php example.php 옵션들...
이렇게 php 를 붙여 주어야 합니다.

php 확장자의 파일을 php.exe 에 직접 연결하여
example.php 옵션들...
이렇게 실행하면, 현재 PHP 5는, 옵션을 제대로 인식하지 못합니다.


그리고 PHP를, Perl 같은 일반 스크립트 언어처럼 사용하는 것은 아직은 좀 무리가 있었습니다. 물론 계속 버전업이 되면 나아지겠지요.

+ Recent posts