가변수(dummy variable)는 해당 범주(category)에 해당하는 경우 '1', 해당하지 않는 경우 '0'으로 값을 입력해주어서 통계나 기계학습을 할 때 컴퓨터가 범주형 자료의 값을 인식할 수 있도록 해줍니다. 


이번 포스팅에서는 Python pandas 라이브러리의 get_dummies() 함수를 사용하여, 


(1) 하나의 cell 당 값이 한개씩 들어있는 범주형 자료를 가지고 가변수 만들기

(2) 하나의 cell 당 범주 값이 여러개씩 들어있는 범주형 자료를 가지고 가변수 만들기


를 해보겠습니다. 


첫번째 것는 간단하구요, 두번째 것은 하나의 cell 안에 들어있는 복수개의 범주형 자료들을 분할(split) 한고 가변수 만드는 작업을 해야 해서 복잡합니다.  첫번째 것은 이전 포스팅(http://rfriend.tistory.com/273)에서 한번 소개했던 적이 있었구요, 이번 포스팅은 두번째 것을 살펴보기 위해서 글을 씁니다. 



  (1) 하나의 cell 당 값이 한개씩 들어있는 범주형 자료를 가지고 가변수 만들기



먼저 필요한 라이브러리들을 불러오고, 음악별 장르를 매핑해놓은 간단한 예제 데이터프레임을 만들어보겠습니다. 



# importing libraries

import numpy as np

import pandas as pd

from pandas import DataFrame

from pandas import Series



# make an example DataFrame

music_df = DataFrame({'music_id': [1, 2, 3, 4, 5], 

                      'music_genre': ['rock', 

                                      'disco', 

                                      'pop', 

                                      'rock', 

                                      'pop']}

                      , columns = ['music_id', 'music_genre'])


In [3]: music_df

Out[3]:

   music_id    music_genre

0 1              rock

1 2              disco

2 3              pop

3 4              rock

4 5              pop

 



위의 범주형 값이 들어있는 'music_genre' 범주형 변수에 대해서 pandas의 get_dummies() 함수를 사용하여 가변수(dummy variable) 을 만들어보겠습니다. 



In [4]: music_dummy_mat = pd.get_dummies(music_df['music_genre'])


In [5]: music_dummy_mat

Out[5]:

     disco       pop      rock

0         0         0         1

1         1         0         0

2         0         1         0

3         0         0         1

4         0         1         0

 



이번에는 (a) 가변수의 변수 이름들 앞에 'genre_' 라는 접두사(prefix)를 붙이고, (b) 원래의 music_df 데이터프레임에다가 가변수를 생성하면서 만든 music_dummy_mat 데이터프레임을 join() 함수를 사용하여 합쳐보겠습니다. 



In [6]: music_dummy_mat = music_df.join(music_dummy_mat.add_prefix('genre_'))


In [7]: music_dummy_mat

Out[7]:

   music_id  music_genre   genre_disco  genre_pop  genre_rock

0       1       rock                0               0                1

1       2       disco               1               0                0

2       3       pop                0                1                0

3       4       rock                0                0                1

4       5       pop                0                1                0

 




  (2) 하나의 cell에 범주 값이 여러개씩 들어있는 범주형 자료를 가지고 가변수 만들기


음악 한개당 구분자는 수직바('|') 로 해서 복수개의 음악 장르 범주 값이 들어있는 예제 데이터프레임을 만들어보겠습니다.  



# making example DataFrame

music_multi_df = DataFrame({'music_id': [1, 2, 3, 4, 5], 

                      'music_genre': ['rock|punk rock|heavy metal', 

                                      'hip hop|reggae', 

                                      'pop|jazz|blues', 

                                      'disco|techo', 

                                      'rhythm and blues|blues|jazz']}

                      , columns = ['music_id', 'music_genre'])

 


In [9]: music_multi_df

Out[9]:

     music_id      music_genre

0      1             rock|punk rock|heavy metal

1      2             hip hop|reggae

2      3             pop|jazz|blues

3      4             disco|techo

4      5             rhythm and blues|blues|jazz




'music_genre' 변수의 각 값에 수직바('|')로 구분되어 묶여있는 여러개의 범주 값들을 split() 문자열 메소드를 사용하여 분리를 한 후에, set.union() 함수를 사용하여 각 음악 장르 범주 값들을 원소로 가지는 하나의 집합을 만들어 보겠습니다. 



In [10]: music_genre_iter = (set(x.split('|')) for x in music_multi_df.music_genre)


In [11]: music_genre_set = sorted(set.union(*music_genre_iter))


In [12]: music_genre_set

Out[12]:

['blues',

 'disco',

 'heavy metal',

 'hip hop',

 'jazz',

 'pop',

 'punk rock',

 'reggae',

 'rhythm and blues',

 'rock',

 'techo']

 



다음으로, np.zeros() 함수를 사용하여 music_multi_df 의 행의 개수만큼의 행과 music_genre_set 의 개수만큼의 열을 가지는 '0'으로 채워진 데이터프레임을 만들어보겠습니다.  '0'만 채워진 데이터프레임은 다음번에 가변수의 '1' 값을 채워나갈 빈 집으로 보면 되겠습니다. 



In [14]: indicator_mat = DataFrame(np.zeros((len(music_multi_df), len(music_genre_set))),

    ...: columns=music_genre_set)


In [15]: indicator_mat

Out[15]:

blues disco heavy metal hip hop jazz pop punk rock reggae \

0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0

1 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0

2 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0

3 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0

4 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0


rhythm and blues rock techo

0 0.0 0.0 0.0

1 0.0 0.0 0.0

2 0.0 0.0 0.0

3 0.0 0.0 0.0

4 0.0 0.0 0.0  

 



이제 for loop 문을 사용하여 각 row 별로 music_genre 의 값을 순회하면서 split() 메소드로 분리를 한 다음에, 각 음악별로 해당 장르를 방금 위에서 '0'으로 자리를 채워두었던 indicator_mat 데이터프레임의 행, 열을 참조하여 해당 위치에 '1'의 값을 입력해주겠습니다. 



In [18]: for i, genre in enumerate(music_multi_df.music_genre):

              indicator_mat.loc[i, genre.split('|')] = 1


In [19]: indicator_mat

Out[19]:

     blues disco heavy metal hip hop jazz pop punk rock reggae \

0      0.0      0.0      1.0      0.0       0.0    0.0      1.0      0.0

1       0.0      0.0      0.0      1.0      0.0    0.0      0.0      1.0

2      1.0      0.0      0.0      0.0       1.0    1.0      0.0      0.0

3      0.0      1.0      0.0      0.0       0.0    0.0      0.0      0.0

4      1.0      0.0      0.0      0.0       1.0    0.0      0.0      0.0


     rhythm and blues      rock      techo

0      0.0                       1.0       0.0

1      0.0                       0.0       0.0

2      0.0                       0.0       0.0

3      0.0                       0.0       1.0

4      1.0                       0.0       0.0  

 



마지막으로, (a) 음악 장르 가변수의 앞 머리에 'genre_' 라는 접두사를 붙이고, (b) 원래의 'music_multi_df' 데이터프레임에 방금전에 새로 만든 'indicator_mat' 가변수 데이터프레임을 join() 함수를 이용하여 합쳐보겠습니다. 



In [20]: music_indicator_mat = music_multi_df.join(indicator_mat.add_prefix('genre_'))


In [21]: music_indicator_mat

Out[21]:

  music_id music_genre genre_blues genre_disco \

0 1 rock|punk rock|heavy metal 0.0 0.0

1 2 hip hop|reggae 0.0 0.0

2 3 pop|jazz|blues 1.0 0.0

3 4 disco|techo 0.0 1.0

4 5 rhythm and blues|blues|jazz 1.0 0.0


  genre_heavy metal genre_hip hop genre_jazz genre_pop genre_punk rock \

0 1.0 0.0 0.0 0.0 1.0

1 0.0 1.0 0.0 0.0 0.0

2 0.0 0.0 1.0 1.0 0.0

3 0.0 0.0 0.0 0.0 0.0

4 0.0 0.0 1.0 0.0 0.0


  genre_reggae genre_rhythm and blues genre_rock genre_techo

0 0.0 0.0 1.0 0.0

1 1.0 0.0 0.0 0.0

2 0.0 0.0 0.0 0.0

3 0.0 0.0 0.0 1.0

4 0.0 1.0 0.0 0.0  


 



많은 도움이 되었기를 바랍니다. 

728x90
반응형
Posted by Rfriend
,

학교 다닐 때 행렬로 연립방정식 풀었던 기억이 날 듯 합니다. 선형대수(Linear Algebra)는 통계, 기계학습, 공학, 영상/이미지 처리 등 여러 분야에서 활용이 됩니다. 선형대수를 전부 다루려면 너무나 방대하므로, 이번 포스팅에서는 Python의 NumPy에 있는 선형대수(Linear Algebra) 함수들 중에서 자주 사용하는 함수에 대해서만 선별적으로 소개하겠습니다. 그리고 선형대수의 이론적인 부분은 별도로 참고할 수 있는 링크를 달도록 하겠습니다. 


  • 단위행렬 (Unit matrix): np.eye(n)
  • 대각행렬 (Diagonal matrix): np.diag(x)
  • 내적 (Dot product, Inner product): np.dot(a, b)
  • 대각합 (Trace): np.trace(x)
  • 행렬식 (Matrix Determinant): np.linalg.det(x)
  • 역행렬 (Inverse of a matrix): np.linalg.inv(x)
  • 고유값 (Eigenvalue), 고유벡터 (Eigenvector): w, v = np.linalg.eig(x)
  • 특이값 분해 (Singular Value Decomposition): u, s, vh = np.linalg.svd(A)
  • 연립방정식 해 풀기 (Solve a linear matrix equation): np.linalg.solve(a, b)
  • 최소자승 해 풀기 (Compute the Least-squares solution): m, c = np.linalg.lstsq(A, y, rcond=None)[0]




 1. 단위행렬 혹은 항등행렬 (Unit matrix, Identity matrix): np.eye(n)


단위행렬은 대각원소가 1이고, 나머지는 모두 0인 n차 정방행렬을 말하며, numpy의 eye() 함수를 사용해서 만들 수 있습니다. 


* 참고 링크 : https://rfriend.tistory.com/141



import numpy as np


unit_mat_4 = np.eye(4)


print(unit_mat_4)

[[1. 0. 0. 0.]
 [0. 1. 0. 0.]
 [0. 0. 1. 0.]
 [0. 0. 0. 1.]]

 




  1. 대각행렬 (Diagonal matrix): np.diag(x)


대각행렬은 대각성분 이외의 모든 성분이 모두 '0'인 n차 정방행렬을 말합니다. 아래 예시의 행렬에서 빨간색으로 표시한 원소를 '0'으로 바꾼 행렬이 대각행렬입니다. 


* 참고 링크 : http://rfriend.tistory.com/141


 

In [1]: import numpy as np


In [2]: x = np.arange(9).reshape(3, 3)


In [3]: print(x)

[[0 1 2]

 [3 4 5]

 [6 7 8]]


In [4]: np.diag(x)

Out[4]: array([0, 4, 8])


In [5]: np.diag(np.diag(x))

Out[5]:

array([[0, 0, 0],

        [0, 4, 0],

        [0, 0, 8]])





  2. 내적 (Dot product, Inner product): np.dot(a, b), a.dot(b)


matrix dot product, inner product, scalar product, projection product

Python에서 '*' 를 사용한 두 행렬 간 곱은 원소 간 곱(element-wise product)을 반환하며, 선형대수에서 말하는 행렬 간 내적 곱을 위해서는 np.dot() 함수를 이용해야 합니다. 


원소 간 곱 (element-wise product)

: a*b

내적 (dot product, inner product)

: np.dot(a, b)

 

In [6]: a = np.arange(4).reshape(2, 2)


In [7]: print(a)

[[0 1]

 [2 3]]


In [8]: a*a

Out[8]:

array([[0, 1],

        [4, 9]])


In [6]: a = np.arange(4).reshape(2, 2)


In [7]: print(a)

[[0 1]

 [2 3]]


In [9]: np.dot(a, a)

Out[9]:

array([[ 2, 3],

        [ 6, 11]])



np.dot(a, b) NumPy 함수와 a.dot(b)의 배열 메소드의 결과는 동일합니다. 



In [10]: a.dot(a)

Out[10]:

array([[ 2, 3],

        [ 6, 11]])

 




  3. 대각합 (Trace): np.trace(x)


정방행렬의 대각에 위치한 원소를 전부 더해줍니다. 

아래의 2차 정방행렬 예의 대각합은 0+5+10+15 = 30 이 됩니다. (파란색으로 표시함)



In [12]: b = np.arange(16).reshape(4, 4)


In [13]: print(b)

[[ 0 1 2 3]

 [ 4 5 6 7]

 [ 8 9 10 11]

 [12 13 14 15]]


In [14]: np.trace(b)

Out[14]: 30

 



3차원 행렬에 대해서도 대각합을 구할 수 있습니다. 2차원은 대각선 부분의 원소 값을 전부 더하면 되지만 3차원 행렬에서는 대각(diagonal)이 어떻게 되나 좀 헷갈릴 수 있겠습니다. 아래의 3차원 행렬의 대각합을 구하는 예를 살펴보면, [0+12+24, 1+13+25, 2+14+26] = [36, 39, 42] 가 됩니다. 



In [15]: c = np.arange(27).reshape(3, 3, 3)


In [16]: print(c)

[[[ 0 1 2]

  [ 3 4 5]

  [ 6 7 8]]


 [[ 9 10 11]

  [12 13 14]

  [15 16 17]]


 [[18 19 20]

  [21 22 23]

  [24 25 26]]]


In [17]: np.trace(c)

Out[17]: array([36, 39, 42])

 




  4. 행렬식 (Matrix Determinant): np.linalg.det(x)


역행렬이 존재하는지 여부를 확인하는 방법으로 행렬식(determinant, 줄여서 det)이라는 지표를 사용합니다. 이 행렬식이 '0'이 아니면 역행렬이 존재하고, 이 행렬식이 '0'이면 역행렬이 존재하지 않습니다. 


* 참고 링크 : http://rfriend.tistory.com/142


아래의 예에서 array([[1, 2], [3, 4]]) 의 행렬식이 '-2.0'으로서, '0'이 아니므로 역행렬이 존재한다고 판단할 수 있습니다. 



In [18]: d = np.array([[1, 2], [3, 4]])


In [19]: np.linalg.det(a)

Out[19]: -2.0

 




  5. 역행렬 (Inverse of a matrix): np.linalg.inv(x)


역행렬은 n차정방행렬 Amn과의 곱이 항등행렬 또는 단위행렬 In이 되는 n차정방행렬을 말합니다. A*B 와 B*A 모두 순서에 상관없이 곱했을 때 단위행렬이 나오는 n차정방행렬이 있다면 역행렬이 존재하는 것입니다.

역행렬은 가우스 소거법(Gauss-Jordan elimination method), 혹은 여인수(cofactor method)로 풀 수 있습니다. 




In [20]: a = np.array(range(4)).reshape(2, 2)


In [21]: print(a)

[[0 1]

 [2 3]]


In [22]: a_inv = np.linalg.inv(a)


In [23]: a_inv

Out[23]:

array([[-1.5, 0.5],

        [ 1. , 0. ]])




위의 예제에서 np.linalg.inv() 함수를 사용하여 푼 역행렬이 제대로 푼 것인지 확인을 해보겠습니다. 역행렬의 정의에 따라서 원래의 행렬에 역행렬을 곱하면, 즉, a.dot(a_inv) 또는 np.dot(a, a_inv) 를 하면 단위행렬(unit matrix)가 되는지 확인해보겠습니다. 



In [24]: a.dot(a_inv)

Out[24]:

array([[1., 0.],

         [0., 1.]])

 




  6. 고유값 (Eigenvalue), 고유벡터 (Eigenvector): w, v = np.linalg.eig(x)


정방행렬 A에 대하여 Ax = λx  (상수 λ) 가 성립하는 0이 아닌 벡터 x가 존재할 때 상수 λ 를 행렬 A의 고유값 (eigenvalue), x 를 이에 대응하는 고유벡터 (eigenvector) 라고 합니다. 


np.linalg.eig() 함수는 고유값(eigenvalue) w, 고유벡터(eigenvector) v 의 두 개의 객체를 반환합니다. 


In [25]: e = np.array([[4, 2],[3, 5]])


In [26]: print(e)

[[4 2]

[3 5]]


In [27]: w, v = np.linalg.eig(e)


#  w: the eigenvalues lambda

In [28]: print(w)

[2. 7.]


# v: the corresponding eigenvectors, one eigenvector per column

In [29]: print(v)

[[-0.70710678 -0.5547002 ]

[ 0.70710678 -0.83205029]]

 



고유벡터는 배열 인덱싱하는 방법을 사용해서 각 고유값에 대응하는 고유벡터를 선택할 수 있습니다. 



# eigenvector of eigenvalue lambda 2

In [30]: print(v[:, 0]

[-0.70710678 0.70710678]


# eigenvector of eigenvalue labmda 7

In [31]: print(v[:, 1]

[-0.5547002 -0.83205029]

 




  7. 특이값 분해 (Singular Value Decomposition): u, s, vh = np.linalg.svd(A)


특이값 분해는 고유값 분해(eigen decomposition)처럼 행렬을 대각화하는 한 방법으로서, 정방행렬뿐만 아니라 모든 m x n 행렬에 대해 적용 가능합니다. 특이값 분해는 차원축소, 데이터 압축 등에 사용할 수 있습니다. 이론적인 부분은 설명하자면 너무 길기 때문에 이 포스팅에서는 설명하지 않겠으며, 아래의 링크를 참고하시기 바랍니다. 


* 참고 링크 : http://rfriend.tistory.com/185


아래의 np.linalg.svd(A) 예제는 위의 참고 링크에서 사용했던 예제와 동일한 것을 사용하였습니다. 


In [32]: A = np.array([[3,6], [2,3], [0,0], [0,0]])


In [33]: print(A)

[[3 6]

 [2 3]

 [0 0]

 [0 0]]


In [34]: u, s, vh = np.linalg.svd(A)


In [35]: print(u)

[[-0.8816746 -0.47185793 0. 0. ]

 [-0.47185793 0.8816746 0. 0. ]

 [ 0. 0. 1. 0. ]

 [ 0. 0. 0. 1. ]]


In [36]: print(s)

[7.60555128 0.39444872]


In [37]: print(vh)

[[-0.47185793 -0.8816746 ]

 [ 0.8816746 -0.47185793]]

 




  8. 연립방정식 해 풀기 (Solve a linear matrix equation): np.linalg.solve(a, b)


아래의 두 개 연립방정식의 해(x0, x1)를 np.linalg.solve(a, b) 함수를 사용하여 풀어보겠습니다. 



위의 연립방정식을 어떻게 행렬로 입력하고, np.linalg.solve(a, b)에 입력하는지 유심히 살펴보시기 바랍니다. 



In [38]: a = np.array([[4, 3], [3, 2]])


In [39]: b = np.array([23, 16])


In [40]: x = np.linalg.solve(a, b)


In [41]: print(x)

[2. 5.]

 



NumPy 가 제대로 x0, x1의 해를 풀었는지 확인해보겠습니다. x0=2, x1=5 가 해 맞네요!



In [42]: np.allclose(np.dot(a, x), b)

Out[42]: True

 




  9. 최소자승 해 풀기 (Compute the Least-squares solution)

     : m, c = np.linalg.lstsq(A, y, rcond=None)[0]


회귀모형 적합할 때 최소자승법(Least-squares method)으로 잔차 제곱합을 최소화하는 회귀계수를 추정합니다. 


* 참고 링크 : https://docs.scipy.org/doc/numpy/reference/generated/numpy.linalg.lstsq.html



아래의 예에서는 회귀계수 m, y절편 c를 최소자승법을 사용해서 구해보겠습니다. 



In [43]: x = np.array([0, 1, 2, 3])


In [44]: y = np.array([-1, 0.2, 0.9, 2.1])


In [45]: A = np.vstack([x, np.ones(len(x))]).T


In [46]: A

Out[46]:

array([[0., 1.],

        [1., 1.],

        [2., 1.],

        [3., 1.]])


In [47]: m, c = np.linalg.lstsq(A, y, rcond=None)[0]


In [48]: print(m, c)

0.9999999999999999 -0.9499999999999997

 



아래의 그래프에서 점은 원래의 데이터이며, 빨간색 선은 최소자승법으로 추정한 회귀식의 적합선이 되겠습니다. 



In [49]: import matplotlib.pyplot as plt

    ...: plt.plot(x, y, 'o', label='Original data', markersize=10)

    ...: plt.plot(x, m*x + c, 'r', label='Fitted line')

    ...: plt.legend()

    ...: plt.show()




많은 도움이 되었기를 바랍니다. 


728x90
반응형
Posted by Rfriend
,

이번 포스팅에서는 도커 허브(Docker Hub)에서 Greenplum Database(이하 GPDB)에 MADlib, PL/R, PL/Python이 설치된 Docker Image를 내려받아 분석 환경을 구성하는 방법을 소개하겠습니다. 


이번 포스팅에서 소개하는 gpdb-analytics 도커 이미지는 개인이 집이나 회사에서 GPDB로 MADlib, PL/R, PL/Python 사용하면서 테스트해보고 공부할 때 간편하게 사용할 수 있는 용도로 만든 것입니다. 



[사전 준비] Dokcer Install


Docker Image를 이용하여 GPDB+분석툴을 설치할 것이므로, 먼저 Docker Hub (https://hub.docker.com/)에서 회원가입을 하고, https://www.docker.com/products/docker-desktop 사이트에서 자신의 OS에 맞는 Docker를 다운로드 받아 설치하시기 바랍니다. 




단, Windows OS 사용자의 경우는 (1) Windows 10 Professional or Enterprise 64-bit 의 경우 'Docker CE for Windows'를 다운받아 설치하시구요, 그 이전 버전 혹은 Home Edition 버전 Windows OS 이용하시는 분의 경우는 'Docker Toolbox'를 다운로드 받아서 설치하시기 바랍니다. 





[ Docker Hub에서 gpdb-analytics 도커 이미지 내려받아서 GPDB 분석 환경 구성하기 ]


1. Docker Hub에서 gpdb-analytics 도커 이미지 내려받기 (docker pull)





(터미널 사용)

## Docker 이미지 내려 받기

$ docker pull hdlee2u/gpdb-analytics

## Docker 이미지 확인 하기

$ docker images

REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
centos                     7                   d123f4e55e12        9 months ago        197MB
hdlee2u/gpdb-base        latest              bfe4e63b8e81         2 years ago           1.17GB

hdlee2u/gpdb-analytics  latest           3be773a1a7e1        About a minute ago   4.93GB

 




2. 도커 이미지를 실행하여 Docker Container 를 생성하고, GPDB 분석 환경 시작하기



## Docker 이미지를 실행/ 5432 기본 포트로, ssh 2022포트를 사용하여 접근 가능하도록 Docker 컨테이너 생성

docker run -i -d -p 5432:5432 -p 28080:28080 --name gpdb-ds --hostname mdw hdlee2u/gpdb-analytics /usr/sbin/sshd -D


## Docker 컨테이너 목록 확인

$ docker ps

CONTAINER ID    IMAGE                   COMMAND                   CREATED             STATUS              PORTS                   NAMES

7518fd48450a        575a7d45999d        "/bin/bash"              1 minute ago         Up 6 hours                  0.0.0.0:5432->5432/tcp, 0.0.0.0:28080->28080/tcp   gpdb-ds



## Start GPDB and Use psql


$ docker exec -it gpdb-ds /bin/bash

[root@mdw /]# su - gpadmin
[gpadmin@mdw ~]$ gpstart -a

20180821:04:45:08:000043 gpstart:mdw:gpadmin-[INFO]:-Starting gpstart with args: -a
20180821:04:45:08:000043 gpstart:mdw:gpadmin-[INFO]:-Gathering information and validating the environment...
20180821:04:45:08:000043 gpstart:mdw:gpadmin-[INFO]:-Greenplum Binary Version: 'postgres (Greenplum Database) 5.10.2 build commit:b3c02f3acd880e2d676dacea36be015e4a3826d4'
20180821:04:45:08:000043 gpstart:mdw:gpadmin-[INFO]:-Greenplum Catalog Version: '301705051'
20180821:04:45:08:000043 gpstart:mdw:gpadmin-[WARNING]:-postmaster.pid file exists on Master, checking if recovery startup required
20180821:04:45:08:000043 gpstart:mdw:gpadmin-[INFO]:-Commencing recovery startup checks
20180821:04:45:08:000043 gpstart:mdw:gpadmin-[INFO]:-Have lock file /tmp/.s.PGSQL.5432 but no process running on port 5432
20180821:04:45:08:000043 gpstart:mdw:gpadmin-[INFO]:-No Master instance process, entering recovery startup mode
20180821:04:45:08:000043 gpstart:mdw:gpadmin-[INFO]:-Clearing Master instance lock files
20180821:04:45:08:000043 gpstart:mdw:gpadmin-[INFO]:-Clearing Master instance pid file
20180821:04:45:08:000043 gpstart:mdw:gpadmin-[INFO]:-Starting Master instance in admin mode
20180821:04:45:10:000043 gpstart:mdw:gpadmin-[INFO]:-Obtaining Greenplum Master catalog information
20180821:04:45:10:000043 gpstart:mdw:gpadmin-[INFO]:-Obtaining Segment details from master...
20180821:04:45:10:000043 gpstart:mdw:gpadmin-[INFO]:-Setting new master era
20180821:04:45:10:000043 gpstart:mdw:gpadmin-[INFO]:-Commencing forced instance shutdown
20180821:04:45:12:000043 gpstart:mdw:gpadmin-[INFO]:-Starting Master instance in admin mode
20180821:04:45:13:000043 gpstart:mdw:gpadmin-[INFO]:-Obtaining Greenplum Master catalog information
20180821:04:45:13:000043 gpstart:mdw:gpadmin-[INFO]:-Obtaining Segment details from master...
20180821:04:45:13:000043 gpstart:mdw:gpadmin-[INFO]:-Setting new master era
20180821:04:45:13:000043 gpstart:mdw:gpadmin-[INFO]:-Master Started...
20180821:04:45:13:000043 gpstart:mdw:gpadmin-[INFO]:-Shutting down master
20180821:04:45:14:000043 gpstart:mdw:gpadmin-[INFO]:-Commencing parallel segment instance startup, please wait...
...
20180821:04:45:17:000043 gpstart:mdw:gpadmin-[INFO]:-Process results...
20180821:04:45:17:000043 gpstart:mdw:gpadmin-[INFO]:-----------------------------------------------------
20180821:04:45:17:000043 gpstart:mdw:gpadmin-[INFO]:-   Successful segment starts                                            = 2
20180821:04:45:17:000043 gpstart:mdw:gpadmin-[INFO]:-   Failed segment starts                                                = 0
20180821:04:45:17:000043 gpstart:mdw:gpadmin-[INFO]:-   Skipped segment starts (segments are marked down in configuration)   = 0
20180821:04:45:17:000043 gpstart:mdw:gpadmin-[INFO]:-----------------------------------------------------
20180821:04:45:17:000043 gpstart:mdw:gpadmin-[INFO]:-Successfully started 2 of 2 segment instances
20180821:04:45:17:000043 gpstart:mdw:gpadmin-[INFO]:-----------------------------------------------------
20180821:04:45:17:000043 gpstart:mdw:gpadmin-[INFO]:-Starting Master instance mdw directory /data/master/gpseg-1
20180821:04:45:18:000043 gpstart:mdw:gpadmin-[INFO]:-Command pg_ctl reports Master mdw instance active
20180821:04:45:18:000043 gpstart:mdw:gpadmin-[INFO]:-No standby master configured.  skipping...
20180821:04:45:18:000043 gpstart:mdw:gpadmin-[INFO]:-Database successfully started
[gpadmin@mdw ~]$
[gpadmin@mdw ~]$

[gpadmin@mdw ~]$ psql
psql (8.3.23)
Type "help" for help.

gpadmin=# \dn
List of schemas
Name | Owner
--------------------+---------
gp_toolkit | gpadmin
information_schema | gpadmin
madlib | gpadmin
pg_aoseg | gpadmin
pg_bitmapindex | gpadmin
pg_catalog | gpadmin
pg_toast | gpadmin
public | gpadmin
(8 rows)

gpadmin=# \q




3. PGAdmin IV 로 GPDB 연결하기


GPDB 5.x 버전에서 SQL Query를 할 때 PGAdmin IV 를 사용합니다. (GPDB 5.x 버전에서는 PGAdmin III 는 작동하지 않으며, 반대로 GPDB 4.x 버전에서는 PGAdmin IV가 작동하지 않고 대신 PGAdmin III만 작동합니다)


PGAdmin IV 는 https://www.pgadmin.org/download/ 에서 다운로드 하여 설치하면 됩니다. 


  • Host : localhost
  • Port : 5432
  • Maintenance DB : gpadmin
  • Username : gpadmin
  • Password : pivotal
  • Group: Servers
  • Ternel port: 22






4. Jupyter Notebook으로 GPDB 연결하기


4-0. Python 2.7 version의 Anaconda 설치


https://www.anaconda.com/download 에서 자신의 OS에 맞는 Python 2.7 version의 Anaconda를 설치합니다. GPDB 5.x 버전은 Python 2.7 version을 지원합니다. 




Anaconda를 설치하였으면, Anaconda Navigator를 실행한 후 base(root) 환경(즉, python 2.7)에서 'Jupyter Notebook'의 Launch 단추를 눌러서 Jupyter Notebook을 실행합니다. 





터미널을 이용해서 가상환경을 조회, 선택하고 Jupyter Notebook을 실행할 수도 있습니다. 




# 가상 환경 리스트 조회

$ conda env list

 

# 가상 환경 선택 (가상환경 리스트에서 python 2.7 버전 선택, windows의 경우: activate env_name)

$ source activate env_name


# Jupyter Notebook 실행

$ jupyter notebook






4-1. pip install 로 추가로 필요한 Python 패키지 설치하기



(터미널에서)

$ pip install --upgrade pip


$ pip install psycopg2

$ pip install sqlalchemy

$ pip install sql_magic

$ pip install math

$ pip install textwrap

$ pip install os

$ pip install Ipython


$ pip install ipywidgets

$ jupyter nbextension enable --py widgetsnbextension

$ pip install pygraphviz





4-2.  Jupyter Notebook에서 DB Connection 설정하기

4-2-1. Python packages importing



# Common modules

import numpy as np

import pandas as pd

from pandas import DataFrame

from pandas import Series

import sklearn

import math

import textwrap as tw


# For DB Connecton

import psycopg2

from sqlalchemy import create_engine

import sql_magic


# For reproducibility

np.random.seed(2622)


# Directory

import os

 



4-2-2. Visualization Parms Setup



import matplotlib as mpl

import matplotlib.pyplot as plt

import seaborn as sns


# To draw plots in jupyter notebook

#%matplotlib inline

%pylab inline


from pylab import rcParams

rcParams['figure.figsize'] = 12, 8

rcParams['axes.labelsize'] = 14

rcParams['xtick.labelsize'] = 12

rcParams['ytick.labelsize'] = 12


pd.set_option('display.max_columns', None)

pd.set_option('display.max_colwidth', 1000)


# Display

import ipywidgets as widgets

import IPython.display as ipd

from IPython.display import display


# interpret string as markdown

def printmd(string):

    ipd.display(ipd.Markdown(string))


# seaborn style

sns.set(style="darkgrid")




4-2-3. Greenplum Database Connection Setup



# put your own GPDB information

user = 'gpadmin'

password = 'pivotal'

host = 'localhost'

db = 'gpadmin'


connection_string = "postgresql://{user}:{password}@{host}/{db}".\

    format(user=user, 

           password=password, 

           host=host, 

           db=db)

    

conn = psycopg2.connect(connection_string)

cur = conn.cursor()

conn.autocommit = True




# helper function

def query_gpdb(query): 


    cur.execute(query)


    colnames = [desc[0] for desc in cur.description]

    return DataFrame(cur.fetchall(), columns=colnames)

 




4-2-4. sql_magic Setup

https://github.com/pivotal-legacy/sql_magic

sql_magic is Jupyter magic for writing SQL to interact with Greenplum/PostgreSQL database, Hive and Spark. Query results are saved directly to a Pandas dataframe.



# sql_magic package and ext sql_magic to query GPDB

%load_ext sql_magic

#%reload_ext sql_magic


# sql_magic

postgres_engine = create_engine(connection_string)


%config SQL.conn_name = 'postgres_engine'


# '%execsql' for sql execution, 

# '%read_sql' for reading table as a DataFrame format

from IPython.core.magic import (register_line_magic, register_cell_magic, register_line_cell_magic)

@register_cell_magic

def execsql(line, cell):

       _ = postgres_engine.execute(cell)

       return

 




드디어 GPDB를 개인 컴퓨터에서 테스트, 공부용으로 간편하게(? ^^;) 설치하여 보았습니다. 수고 많으셨습니다. 




Jupyter Notebook 에서 sql 매직 언어로 DB를 조회할 수 있습니다. 


# GPDB 버전 확인

%read_sql select version();



# GPDB instance 확인 (하나의 서버에 1개 master, 2개 segment가 설치된 경우임)

%read_sql select * from pg_catalog.gp_segment_configuration 



# MADlib version 확인

%read_sql select madlib.version();



# PL/Languages 확인


sql query가 두 줄 이상일 경우 %%read_sql 처럼 % 두개를 앞에 써줍니다. (sql query 가 한 줄일 경우 %read_sql)

%%read_sql 

select * 

    from pg_catalog.pg_language;



# Table 생성

%%execsql

drop table if exists tmp;

create table tmp (

    id int, 

    var1 varchar(10)

    );




5. Docker Container 중단, 재시작, 작동 중인 컨테이너 목록 확인



## Docker  컨테이너 중단, 재시작, 목록 확인

$ docker stop gpdb-ds

$ docker start gpdb-ds

$ docker ps

CONTAINER ID    IMAGE                   COMMAND                   CREATED             STATUS              PORTS                   NAMES
7518fd48450a        575a7d45999d        "/bin/bash"              2 minutes ago         Up 6 hours                  0.0.0.0:5432->5432/tcp, 0.0.0.0:28080->28080/tcp   gpdb-ds

 



많은 도움이 되었기를 바랍니다. 



---------------

혹시 아래와 같은 에러가 발생하는 경우 http://rfriend.tistory.com/396 포스팅을 참고하세요. 



Error response from daemon: driver failed programming external connectivity on endpoint gpdb-ds (d519c381360008f0ac0e8d756e97aeb0538075ee1b7e35862a0eaedf887181f1): Error starting userland proxy: Bind for 0.0.0.0:5432 failed: port is already allocated

Error: failed to start containers: gpdb-ds 





728x90
반응형
Posted by Rfriend
,

이번 포스팅에서는 기본 Greenplum Database (이하 GPDB) 도커 이미지를 내려받아서, 그 위에 대용량 데이터 통계분석, 기계학습에 활용하는 MADlib, PL/R, PL/Python을 설치한 Docker Image 만든 후, Docker Hub에 올리는 일련의 절차에 대해서 소개하겠습니다. 


이번 포스팅은 도커로 GPDB 기반 분석 환경을 구성하는 절차로서, 데이터 엔지니어링에 관심있으신 분에게 도움이 될 것 같습니다. 혹시 데이터 분석으로 바로 넘어가고 싶은 분은 다음번 포스팅(http://rfriend.tistory.com/379)을 참고하시면 되며, 이번 포스팅을 skip 하여도 아무런 문제 없이 도커를 사용하여 GPDB 기반 분석 환경을 바로 바로 이용하실 수 있습니다. 



[ GPDB 기본 도커 이미지에 MADlib, PL/R, PL/Python 설치 후 gpdb-analytics 도커 이미지 새로 만들어서 Docker Hub에 올리기 절차 ]






0. Dokcer Hub 회원 가입 및 Docker Desktop 다운로드/설치




Windows OS 사용자의 경우 자신의 Windows 버전에 맞게 'Docker CE for Windows' 혹은 'Docker Toolbox'를 다운로드 받아 설치하면 됩니다. 





1. Docker Hub에서 기본 GPDB 이미지를 pull 해서 사용하기

 

<터미널 사용>

1-1.docker image download



docker pull hdlee2u/gpdb-base

docker images

REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE

centos                  7                   d123f4e55e12        9 months ago        197MB

hdlee2u/gpdb-base      latest              bfe4e63b8e81        2 years ago         1.17GB

 




1-2.docker image
실행/ 5432를 기본 포트로, ,ssh2022포트를 사용하여 접근 가능하도록 docker 이미지 실행 



docker run -i -d -p 5432:5432 -p 2022:22 --name gpdb  hdlee2u/gpdb-base

docker ps -a

 




1-3.docker image
중단, 시작 후 동작 상태 확인 



docker stop gpdb

docker start gpdb

docker ps

CONTAINER ID    IMAGE                   COMMAND                   CREATED             STATUS              PORTS                   NAMES

4e6b947be0d6    hdlee2u/gpdb-base   "/bin/sh -c 'echo \"1…"   29 hours ago        Up 3 hours        0.0.0.0:5432->5432/tcp, 0.0.0.0:2022->22/tcp   gpdb

ihongdon-ui-MacBook-Pro:~ ihongdon$

 




2. Docker GPDBMADlib 설치하기

 

2-1. GPDB version 확인 (PGAdmin III 에서)



# select version()

 

PostgreSQL 8.2.15 (Greenplum Database 4.3.7.1 build 1) on x86_64-unknown-linux-gnu, compiled by GCC gcc (GCC) 4.4.2 compiled on Jan 21 2016 15:51:02

 




2-2.Pivotal Network(https://network.pivotal.io)
에서 MADlib 다운로드 (회원가입 필요) 


Pivotal Greenplum Releases: 4.3.18.0 버전 카테고리에서

>> Greenplum Advanced Analytics 선택

>> MADlib 1.12 다운로드

(https://network.pivotal.io/products/pivotal-gpdb/#/releases/8538/file_groups/764)

 






2-3. MADlib downloads 한 파일을 docker로 복사



cd Downloads/

ls

madlib-1.12-gp4.3-rhel5-x86_64.tar.gz

 



docker exec -i -t gpdb /bin/bash

[root@4e6b947be0d6 ~]# mkdir /setup

 

[참고파일 옮길 때

[root@4e6b947be0d6 ~]# mv mad* /setup/

 




2-4. docker container 내부의 /bin/bash 프로세스 실행 후, MADlib 파일을 Docker GPDB에 복사하기

 

다른 터미널의 Downloads 경로에서


docker cp madlib-1.12-gp4.3-rhel5-x86_64.tar.gz gpdb:/setup/



[root@4e6b947be0d6 ~]# chown -R gpadmin:gpadmin /setup

[root@4e6b947be0d6 ~]# cd /setup

[root@4e6b947be0d6 setup]# ls -la

total 7492

drwxr-xr-x 2 gpadmin gpadmin    4096 Aug  8 07:44 .

drwxr-xr-x 1 root    root       4096 Aug  8 07:44 ..

-rw-r--r-- 1 gpadmin gpadmin 3932160 Aug  8 05:10 madlib-1.12-gp4.3-rhel5-x86_64.tar

-rw-r--r-- 1 gpadmin gpadmin 3728292 Aug 29  2017 madlib-ossv1.12_pv1.9.9_gpdb4.3orca-rhel5-x86_64.gppkg

 




2-5. 권한 부여

 


[root@4e6b947be0d6 ~]# chown -R gpadmin:gpadmin /setup

[root@4e6b947be0d6 ~]# cd /setup

[root@4e6b947be0d6 setup]# ls -la

total 7492

drwxr-xr-x 2 gpadmin gpadmin    4096 Aug  8 07:44 .

drwxr-xr-x 1 root    root       4096 Aug  8 07:44 ..

-rw-r--r-- 1 gpadmin gpadmin 3932160 Aug  8 05:10 madlib-1.12-gp4.3-rhel5-x86_64.tar

-rw-r--r-- 1 gpadmin gpadmin 3728292 Aug 29  2017 madlib-ossv1.12_pv1.9.9_gpdb4.3orca-rhel5-x86_64.gppkg

 




2-6. MADlib 압축 풀고 설치하기



[root@4e6b947be0d6 setup]# su - gpadmin

-bash-4.1$ cd /setup

-bash-4.1$ ls -la

total 7492

drwxr-xr-x 2 gpadmin gpadmin    4096 Aug  8 07:44 .

drwxr-xr-x 1 root    root       4096 Aug  8 07:44 ..

-rw-r--r-- 1 gpadmin gpadmin 3932160 Aug  8 05:10 madlib-1.12-gp4.3-rhel5-x86_64.tar

 

-bash-4.1$ tar xf madlib-1.12-gp4.3-rhel5-x86_64.tar

-bash-4.1$ ls -la

total 7692

drwxr-xr-x 2 gpadmin gpadmin    4096 Aug  8 07:45 .

drwxr-xr-x 1 root    root       4096 Aug  8 07:44 ..

-rw-r--r-- 1 gpadmin gpadmin 3932160 Aug  8 05:10 madlib-1.12-gp4.3-rhel5-x86_64.tar

-rw-r--r-- 1 gpadmin gpadmin 3728292 Aug 29  2017 madlib-ossv1.12_pv1.9.9_gpdb4.3orca-rhel5-x86_64.gppkg

-rw-r--r-- 1 gpadmin gpadmin  135530 Aug 29  2017 open_source_license_MADlib_1.12_GA.txt

-rw-r--r-- 1 gpadmin gpadmin   51900 Aug 29  2017 ReleaseNotes.txt

 

-bash-4.1$ gppkg -i madlib-ossv1.12_pv1.9.9_gpdb4.3orca-rhel5-x86_64.gppkg

20180808:07:47:11:000512 gppkg:4e6b947be0d6:gpadmin-[INFO]:-Starting gppkg with args: -i madlib-ossv1.12_pv1.9.9_gpdb4.3orca-rhel5-x86_64.gppkg

20180808:07:47:11:000512 gppkg:4e6b947be0d6:gpadmin-[INFO]:-Installing package madlib-ossv1.12_pv1.9.9_gpdb4.3orca-rhel5-x86_64.gppkg

20180808:07:47:11:000512 gppkg:4e6b947be0d6:gpadmin-[INFO]:-Validating rpm installation cmdStr='rpm --test -i /usr/local/greenplum-db-4.3.7.1/.tmp/madlib-1.12-1.x86_64.rpm --dbpath /usr/local/greenplum-db-4.3.7.1/share/packages/database --prefix /usr/local/greenplum-db-4.3.7.1'

20180808:07:47:11:000512 gppkg:4e6b947be0d6:gpadmin-[INFO]:-Installing madlib-ossv1.12_pv1.9.9_gpdb4.3orca-rhel5-x86_64.gppkg locally

20180808:07:47:11:000512 gppkg:4e6b947be0d6:gpadmin-[INFO]:-Validating rpm installation cmdStr='rpm --test -i /usr/local/greenplum-db-4.3.7.1/.tmp/madlib-1.12-1.x86_64.rpm --dbpath /usr/local/greenplum-db-4.3.7.1/share/packages/database --prefix /usr/local/greenplum-db-4.3.7.1'

20180808:07:47:11:000512 gppkg:4e6b947be0d6:gpadmin-[INFO]:-Installing rpms cmdStr='rpm -i /usr/local/greenplum-db-4.3.7.1/.tmp/madlib-1.12-1.x86_64.rpm --dbpath /usr/local/greenplum-db-4.3.7.1/share/packages/database --prefix=/usr/local/greenplum-db-4.3.7.1'

20180808:07:47:12:000512 gppkg:4e6b947be0d6:gpadmin-[INFO]:-Completed local installation of madlib-ossv1.12_pv1.9.9_gpdb4.3orca-rhel5-x86_64.gppkg.

20180808:07:47:12:000512 gppkg:4e6b947be0d6:gpadmin-[INFO]:-Please run the following command to deploy MADlib

usage:  madpack install [-s schema_name] -p greenplum -c user@host:port/database

Example:

       $ $GPHOME/madlib/bin/madpack install -s madlib -p greenplum -c gpadmin@mdw:5432/testdb

       This will install MADlib objects into a Greenplum database named "testdb"

       running on server "mdw" on port 5432. Installer will try to login as "gpadmin"

       and will prompt for password. The target schema will be "madlib".

       To upgrade to a new version of MADlib from version v1.0 or later, use option "upgrade",

       instead of "install"

For additional options run:

$ madpack --help

Release notes and additional documentation can be found at http://madlib.apache.org

20180808:07:47:12:000512 gppkg:4e6b947be0d6:gpadmin-[INFO]:-madlib-ossv1.12_pv1.9.9_gpdb4.3orca-rhel5-x86_64.gppkg successfully installed.

-bash-4.1$  madpack install ^C

-bash-4.1$ hostname

4e6b947be0d6

-bash-4.1$ cat /etc/hosts

127.0.0.1       localhost

::1      localhost ip6-localhost ip6-loopback

fe00::0 ip6-localnet

ff00::0 ip6-mcastprefix

ff02::1 ip6-allnodes

ff02::2 ip6-allrouters

172.17.0.2     4e6b947be0d6

127.0.0.1 72ba20be3774

 




Database list 확인


 

-bash-4.1$ psql

psql (8.2.15)

Type "help" for help.

 

gpadmin=# \l

                  List of databases

   Name    |  Owner  | Encoding |  Access privileges 

-----------+---------+----------+---------------------

 gpadmin   | gpadmin | UTF8     |

 postgres  | gpadmin | UTF8     |

 template0 | gpadmin | UTF8     | =c/gpadmin         

                                : gpadmin=CTc/gpadmin

 template1 | gpadmin | UTF8     | =c/gpadmin         

                                : gpadmin=CTc/gpadmin

(4 rows)

 

gpadmin=# \q




-bash-4.1$ $GPHOME/madlib/bin/madpack install -s madlib -p greenplum -c gpadmin@127.0.0.1:5432/gpadmin

madpack.py : INFO : Detected Greenplum DB version 4.3.7.

madpack.py : INFO : *** Installing MADlib ***

madpack.py : INFO : MADlib tools version    = 1.12 (/usr/local/greenplum-db-4.3.7.1/madlib/Versions/1.12/bin/../madpack/madpack.py)

madpack.py : INFO : MADlib database version = None (host=127.0.0.1:5432, db=gpadmin, schema=madlib)

madpack.py : INFO : Testing PL/Python environment...

madpack.py : INFO : > Creating language PL/Python...

madpack.py : INFO : > PL/Python environment OK (version: 2.6.2)

madpack.py : INFO : Installing MADlib into MADLIB schema...

madpack.py : INFO : > Creating MADLIB schema

madpack.py : INFO : > Creating MADLIB.MigrationHistory table

madpack.py : INFO : > Writing version info in MigrationHistory table

madpack.py : INFO : > Creating objects for modules:

madpack.py : INFO : > - array_ops

madpack.py : INFO : > - bayes

madpack.py : INFO : > - crf

madpack.py : INFO : > - elastic_net

madpack.py : INFO : > - linalg

madpack.py : INFO : > - pmml

madpack.py : INFO : > - prob

madpack.py : INFO : > - sketch

madpack.py : INFO : > - svec

madpack.py : INFO : > - svm

madpack.py : INFO : > - tsa

madpack.py : INFO : > - stemmer

madpack.py : INFO : > - conjugate_gradient

madpack.py : INFO : > - knn

madpack.py : INFO : > - lda

madpack.py : INFO : > - stats

madpack.py : INFO : > - svec_util

madpack.py : INFO : > - utilities

madpack.py : INFO : > - assoc_rules

madpack.py : INFO : > - convex

madpack.py : INFO : > - glm

madpack.py : INFO : > - graph

madpack.py : INFO : > - linear_systems

madpack.py : INFO : > - recursive_partitioning

madpack.py : INFO : > - regress

madpack.py : INFO : > - sample

madpack.py : INFO : > - summary

madpack.py : INFO : > - kmeans

madpack.py : INFO : > - pca

madpack.py : INFO : > - validation

madpack.py : INFO : MADlib 1.12 installed successfully in MADLIB schema.

 



 

스키마 리스트 & MADlib 버전 확인



-bash-4.1$ psql

psql (8.2.15)

Type "help" for help.

 

gpadmin=# \dn

       List of schemas

        Name        |  Owner 

--------------------+---------

 gp_toolkit         | gpadmin

 information_schema | gpadmin

 madlib             | gpadmin

 pg_aoseg           | gpadmin

 pg_bitmapindex     | gpadmin

 pg_catalog         | gpadmin

 pg_toast           | gpadmin

 public             | gpadmin

(8 rows)

 

gpadmin=# select madlib.version();

MADlib version: 1.12, git revision: rc/1.12-rc1, cmake configuration time: Wed Aug 23 22:33:09 UTC 2017, build type: Release, build system: Linux-2.6.18-238.27.1.el5.hot

fix.bz516490, C compiler: gcc 4.4.0, C++ compiler: g++ 4.4.0

(1 row)

 

---- MADlib 설치 성공 완료! ----

 

gpadmin=# \q

 




3. Docker GPDB
PL/R 설치하기 

 

Cent OS 버전 확인하기



-bash-4.1$ cat /etc/redhat-release

CentOS release 6.7 (Final)

 




3-1. Pivotal Network에서 PL/R 다운로드 하기

Pivotal Greenplum Releases: 4.3.18.0 카테고리에서

>> Greenplum Procedural Languages

>> PL/R for RHEL 6 다운로드

(https://network.pivotal.io/products/pivotal-gpdb/#/releases/8538/file_groups/768)

 




3-2. (다른 터미널에서) Docker GPDB/setup 폴더로 PL/R 복사하기



ihongdon-ui-MacBook-Pro:~ ihongdon$ cd Downloads/

ihongdon-ui-MacBook-Pro:Downloads ihongdon$ ls -la

total 90512

-rw-r--r--@  1 ihongdon  staff   3788987  8  8 14:10 madlib-1.12-gp4.3-rhel5-x86_64.tar.gz

-rw-r--r--@  1 ihongdon  staff  39640735  8  8 16:51 plr-2.3.1-GPDB4.3-rhel6-x86_64.gppkg

 

ihongdon-ui-MacBook-Pro:Downloads ihongdon$ docker cp plr-2.3.1-GPDB4.3-rhel6-x86_64.gppkg gpdb:/setup

 




3-3. (Docker
터미널에서) 권한 부여하기 및 gpadmin 들어가기 



[root@4e6b947be0d6 setup]# su - gpadmin

-bash-4.1$ ls

madlib-1.12-gp4.3-rhel5-x86_64.tar                     

open_source_license_MADlib_1.12_GA.txt  ReleaseNotes.txt

madlib-ossv1.12_pv1.9.9_gpdb4.3orca-rhel5-x86_64.gppkg 

plr-2.3.1-GPDB4.3-rhel6-x86_64.gppkg

-bash-4.1$ exit

logout

 

[root@4e6b947be0d6 setup]# chown gpadmin:gpadmin plr-2.3.1-GPDB4.3-rhel6-x86_64.gppkg

 

 [root@4e6b947be0d6 setup]# su - gpadmin

-bash-4.1$ cd /setup

-bash-4.1$ ls

madlib-1.12-gp4.3-rhel5-x86_64.tar                     

open_source_license_MADlib_1.12_GA.txt  ReleaseNotes.txt

madlib-ossv1.12_pv1.9.9_gpdb4.3orca-rhel5-x86_64.gppkg 

plr-2.3.1-GPDB4.3-rhel6-x86_64.gppkg

 

-bash-4.1$ ls -la

total 46404

drwxr-xr-x 2 gpadmin gpadmin     4096 Aug  8 07:52 .

drwxr-xr-x 1 root    root        4096 Aug  8 07:44 ..

-rw-r--r-- 1 gpadmin gpadmin  3932160 Aug  8 05:10 madlib-1.12-gp4.3-rhel5-x86_64.tar

-rw-r--r-- 1 gpadmin gpadmin      566 Aug 29  2017 ._madlib-ossv1.12_pv1.9.9_gpdb4.3orca-rhel5-x86_64.gppkg

-rw-r--r-- 1 gpadmin gpadmin  3728292 Aug 29  2017 madlib-ossv1.12_pv1.9.9_gpdb4.3orca-rhel5-x86_64.gppkg

-rw-r--r-- 1 gpadmin gpadmin     1362 Aug 29  2017 ._open_source_license_MADlib_1.12_GA.txt

-rw-r--r-- 1 gpadmin gpadmin   135530 Aug 29  2017 open_source_license_MADlib_1.12_GA.txt

-rw-r--r-- 1 gpadmin gpadmin 39640735 Aug  8 07:51 plr-2.3.1-GPDB4.3-rhel6-x86_64.gppkg

-rw-r--r-- 1 gpadmin gpadmin      594 Aug 29  2017 ._ReleaseNotes.txt

-rw-r--r-- 1 gpadmin gpadmin    51900 Aug 29  2017 ReleaseNotes.txt

 



 

3-4. PL/R 설치



-bash-4.1$ gppkg -i plr-2.3.1-GPDB4.3-rhel6-x86_64.gppkg

20180808:07:53:41:006779 gppkg:4e6b947be0d6:gpadmin-[INFO]:-Starting gppkg with args: -i plr-2.3.1-GPDB4.3-rhel6-x86_64.gppkg

20180808:07:53:42:006779 gppkg:4e6b947be0d6:gpadmin-[INFO]:-Installing package plr-2.3.1-GPDB4.3-rhel6-x86_64.gppkg

20180808:07:53:42:006779 gppkg:4e6b947be0d6:gpadmin-[INFO]:-Validating rpm installation cmdStr='rpm --test -i /usr/local/greenplum-db-4.3.7.1/.tmp/R-3.3.3-1.x86_64.rpm /usr/local/greenplum-db-4.3.7.1/.tmp/plr-2.3-1.x86_64.rpm --dbpath /usr/local/greenplum-db-4.3.7.1/share/packages/database --prefix /usr/local/greenplum-db-4.3.7.1'

20180808:07:53:42:006779 gppkg:4e6b947be0d6:gpadmin-[INFO]:-Installing plr-2.3.1-GPDB4.3-rhel6-x86_64.gppkg locally

20180808:07:53:42:006779 gppkg:4e6b947be0d6:gpadmin-[INFO]:-Validating rpm installation cmdStr='rpm --test -i /usr/local/greenplum-db-4.3.7.1/.tmp/R-3.3.3-1.x86_64.rpm /usr/local/greenplum-db-4.3.7.1/.tmp/plr-2.3-1.x86_64.rpm --dbpath /usr/local/greenplum-db-4.3.7.1/share/packages/database --prefix /usr/local/greenplum-db-4.3.7.1'

20180808:07:53:42:006779 gppkg:4e6b947be0d6:gpadmin-[INFO]:-Installing rpms cmdStr='rpm -i /usr/local/greenplum-db-4.3.7.1/.tmp/R-3.3.3-1.x86_64.rpm /usr/local/greenplum-db-4.3.7.1/.tmp/plr-2.3-1.x86_64.rpm --dbpath /usr/local/greenplum-db-4.3.7.1/share/packages/database --prefix=/usr/local/greenplum-db-4.3.7.1'

20180808:07:53:45:006779 gppkg:4e6b947be0d6:gpadmin-[INFO]:-Completed local installation of plr-2.3.1-GPDB4.3-rhel6-x86_64.gppkg.

20180808:07:53:45:006779 gppkg:4e6b947be0d6:gpadmin-[INFO]:--

==========================================================================

PL/R installation is complete! To proceed, follow these steps:

1. Source your new $GPHOME/greenplum_path.sh file and restart the database.

2. Create PL/R language in the target database with "createlang plr -d mydatabase"

3. Optionally you can enable PL/R helper functions in this database by running

    "psql -f $GPHOME/share/postgresql/contrib/plr.sql -d mydatabase"

==========================================================================

20180808:07:53:45:006779 gppkg:4e6b947be0d6:gpadmin-[INFO]:-plr-2.3.1-GPDB4.3-rhel6-x86_64.gppkg successfully installed.

 




3-5. GPDB stop
 



-bash-4.1$ gpstop -af

20180808:07:54:30:006833 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Starting gpstop with args: -af

20180808:07:54:30:006833 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Gathering information and validating the environment...

20180808:07:54:30:006833 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Obtaining Greenplum Master catalog information

20180808:07:54:30:006833 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Obtaining Segment details from master...

20180808:07:54:30:006833 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Greenplum Version: 'postgres (Greenplum Database) 4.3.7.1 build 1'

20180808:07:54:30:006833 gpstop:4e6b947be0d6:gpadmin-[INFO]:-There are 2 connections to the database

20180808:07:54:30:006833 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Commencing Master instance shutdown with mode='fast'

20180808:07:54:30:006833 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Master host=72ba20be3774

20180808:07:54:30:006833 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Detected 2 connections to database

20180808:07:54:30:006833 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Switching to WAIT mode

20180808:07:54:30:006833 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Will wait for shutdown to complete, this may take some time if

20180808:07:54:30:006833 gpstop:4e6b947be0d6:gpadmin-[INFO]:-there are a large number of active complex transactions, please wait...

20180808:07:54:30:006833 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Commencing Master instance shutdown with mode=fast

20180808:07:54:30:006833 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Master segment instance directory=/gpdata/master/gpseg-1

20180808:07:54:31:006833 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Attempting forceful termination of any leftover master process

20180808:07:54:31:006833 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Terminating processes for segment /gpdata/master/gpseg-1

20180808:07:54:31:006833 gpstop:4e6b947be0d6:gpadmin-[INFO]:-No standby master host configured

20180808:07:54:31:006833 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Commencing parallel segment instance shutdown, please wait...

20180808:07:54:31:006833 gpstop:4e6b947be0d6:gpadmin-[INFO]:-0.00% of jobs completed

20180808:07:54:41:006833 gpstop:4e6b947be0d6:gpadmin-[INFO]:-100.00% of jobs completed

20180808:07:54:41:006833 gpstop:4e6b947be0d6:gpadmin-[INFO]:-----------------------------------------------------

20180808:07:54:41:006833 gpstop:4e6b947be0d6:gpadmin-[INFO]:-   Segments stopped successfully      = 2

20180808:07:54:41:006833 gpstop:4e6b947be0d6:gpadmin-[INFO]:-   Segments with errors during stop   = 0

20180808:07:54:41:006833 gpstop:4e6b947be0d6:gpadmin-[INFO]:-----------------------------------------------------

20180808:07:54:41:006833 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Successfully shutdown 2 of 2 segment instances

20180808:07:54:41:006833 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Database successfully shutdown with no errors reported

20180808:07:54:41:006833 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Cleaning up leftover gpmmon process

20180808:07:54:41:006833 gpstop:4e6b947be0d6:gpadmin-[INFO]:-No leftover gpmmon process found

20180808:07:54:41:006833 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Cleaning up leftover gpsmon processes

20180808:07:54:41:006833 gpstop:4e6b947be0d6:gpadmin-[INFO]:-No leftover gpsmon processes on some hosts. not attempting forceful termination on these hosts

20180808:07:54:41:006833 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Cleaning up leftover shared memory

 




3-6.
Source your new $GPHOME/greenplum_path.sh file 



-bash-4.1$ vi ~/.bash_profile

-bash-4.1$ source ~/.bash_profile

-bash-4.1$ env | grep R

MASTER_DATA_DIRECTORY=/gpdata/master/gpseg-1

TERM=xterm

USER=gpadmin

LD_LIBRARY_PATH=/usr/local/greenplum-db/./ext/R-3.3.3/lib:/usr/local/greenplum-db/./ext/R-3.3.3/extlib:

/usr/local/greenplum-db/./lib:

/usr/local/greenplum-db/./ext/python/lib:/usr/local/greenplum-db/./lib:/usr/local/greenplum-db/./ext/python/lib:

LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:

su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:

*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:

*.tbz=01;31:*.tbz2=01;31:*.bz=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:

*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:

*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:

*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.ogm=01;35:

*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:

*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:

*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:

*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:

*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:

PATH=/usr/local/greenplum-db/./ext/R-3.3.3/bin:/usr/local/greenplum-db/./bin:/usr/local/greenplum-db/./ext/python/bin:/usr/local/greenplum-db/./bin:/usr/local/greenplum-db/./ext/python/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin

HISTCONTROL=ignoredups

R_HOME=/usr/local/greenplum-db/./ext/R-3.3.3

G_BROKEN_FILENAMES=1

 




3-7.
Create PL/R language in the target database with "createlang plr -d mydatabase" and restart the database. 



-bash-4.1$ createlang plr -d gpadmin

createlang: could not connect to database gpadmin: could not connect to server: No such file or directory

         Is the server running locally and accepting

         connections on Unix domain socket "/tmp/.s.PGSQL.5432"?

 

-bash-4.1$ gpstart -a

20180808:07:56:17:006995 gpstart:4e6b947be0d6:gpadmin-[INFO]:-Starting gpstart with args: -a

20180808:07:56:17:006995 gpstart:4e6b947be0d6:gpadmin-[INFO]:-Gathering information and validating the environment...

20180808:07:56:17:006995 gpstart:4e6b947be0d6:gpadmin-[INFO]:-Greenplum Binary Version: 'postgres (Greenplum Database) 4.3.7.1 build 1'

20180808:07:56:17:006995 gpstart:4e6b947be0d6:gpadmin-[INFO]:-Greenplum Catalog Version: '201310150'

20180808:07:56:17:006995 gpstart:4e6b947be0d6:gpadmin-[INFO]:-Starting Master instance in admin mode

20180808:07:56:18:006995 gpstart:4e6b947be0d6:gpadmin-[INFO]:-Obtaining Greenplum Master catalog information

20180808:07:56:18:006995 gpstart:4e6b947be0d6:gpadmin-[INFO]:-Obtaining Segment details from master...

20180808:07:56:18:006995 gpstart:4e6b947be0d6:gpadmin-[INFO]:-Setting new master era

20180808:07:56:18:006995 gpstart:4e6b947be0d6:gpadmin-[INFO]:-Master Started...

20180808:07:56:18:006995 gpstart:4e6b947be0d6:gpadmin-[INFO]:-Shutting down master

20180808:07:56:19:006995 gpstart:4e6b947be0d6:gpadmin-[INFO]:-Commencing parallel segment instance startup, please wait...

..

20180808:07:56:21:006995 gpstart:4e6b947be0d6:gpadmin-[INFO]:-Process results...

20180808:07:56:21:006995 gpstart:4e6b947be0d6:gpadmin-[INFO]:-----------------------------------------------------

20180808:07:56:21:006995 gpstart:4e6b947be0d6:gpadmin-[INFO]:-   Successful segment starts                                            = 2

20180808:07:56:21:006995 gpstart:4e6b947be0d6:gpadmin-[INFO]:-   Failed segment starts                                                = 0

20180808:07:56:21:006995 gpstart:4e6b947be0d6:gpadmin-[INFO]:-   Skipped segment starts (segments are marked down in configuration)   = 0

20180808:07:56:21:006995 gpstart:4e6b947be0d6:gpadmin-[INFO]:-----------------------------------------------------

20180808:07:56:21:006995 gpstart:4e6b947be0d6:gpadmin-[INFO]:-

20180808:07:56:21:006995 gpstart:4e6b947be0d6:gpadmin-[INFO]:-Successfully started 2 of 2 segment instances

20180808:07:56:21:006995 gpstart:4e6b947be0d6:gpadmin-[INFO]:-----------------------------------------------------

20180808:07:56:21:006995 gpstart:4e6b947be0d6:gpadmin-[INFO]:-Starting Master instance 72ba20be3774 directory /gpdata/master/gpseg-1

20180808:07:56:22:006995 gpstart:4e6b947be0d6:gpadmin-[INFO]:-Command pg_ctl reports Master 72ba20be3774 instance active

20180808:07:56:23:006995 gpstart:4e6b947be0d6:gpadmin-[INFO]:-No standby master configured.  skipping...

20180808:07:56:23:006995 gpstart:4e6b947be0d6:gpadmin-[INFO]:-Database successfully started

 

-bash-4.1$ psql -f $GPHOME/share/postgresql/contrib/plr.sql -d gpadmin

SET

CREATE FUNCTION

CREATE FUNCTION

CREATE FUNCTION

REVOKE

CREATE FUNCTION

 

-bash-4.1$ exit

logout

 



 

4. DataSciencePython(PL/Python), DataScienceR 설치하기

 

4-1. Pivotal Network에서 PL/Python 다운로드 하기

Pivotal Greenplum Releases: 4.3.18.0 카테고리에서

>> Greenplum Procedural Languages

>> Python Data Science Package for RHEL 6다운로드

>> R Data Science Package for RHEL 6 다운로드

(https://network.pivotal.io/products/pivotal-gpdb/#/releases/8538/file_groups/768)

 


4-2. (다른 터미널에서) Docker GPDB로 파일 복사하기



ihongdon-ui-MacBook-Pro:Downloads ihongdon$ ls -la

total 549520

-rw-r--r--@  1 ihongdon  staff  103557483  8  8 16:58 DataSciencePython-1.0.0-gp4-rhel6-x86_64.gppkg

-rw-r--r--@  1 ihongdon  staff  114736878  8  8 16:58 DataScienceR-1.0.0-gp4-rhel6-x86_64.gppkg

-rw-r--r--@  1 ihongdon  staff    3788987  8  8 14:10 madlib-1.12-gp4.3-rhel5-x86_64.tar.gz

-rw-r--r--@  1 ihongdon  staff   39640735  8  8 16:51 plr-2.3.1-GPDB4.3-rhel6-x86_64.gppkg

 

ihongdon-ui-MacBook-Pro:Downloads ihongdon$ docker cp DataSciencePython-1.0.0-gp4-rhel6-x86_64.gppkg gpdb:/setup

ihongdon-ui-MacBook-Pro:Downloads ihongdon$ docker cp DataScienceR-1.0.0-gp4-rhel6-x86_64.gppkg gpdb:/setup

 




4-3. (Docker
터미널에서) 권한 부여 및 gpadmin 들어가기 



[root@4e6b947be0d6 setup]# chown gpadmin:gpadmin *.gppkg

[root@4e6b947be0d6 setup]# su - gpadmin

-bash-4.1$ ls

gpAdminLogs

-bash-4.1$ cd  /setup

-bash-4.1$ ls

DataSciencePython-1.0.0-gp4-rhel6-x86_64.gppkg 

madlib-1.12-gp4.3-rhel5-x86_64.tar                     

open_source_license_MADlib_1.12_GA.txt 

ReleaseNotes.txt

DataScienceR-1.0.0-gp4-rhel6-x86_64.gppkg      

madlib-ossv1.12_pv1.9.9_gpdb4.3orca-rhel5-x86_64.gppkg 

plr-2.3.1-GPDB4.3-rhel6-x86_64.gppkg

 

-bash-4.1$ ls -la

total 259584

drwxr-xr-x 2 gpadmin gpadmin      4096 Aug  8 07:59 .

drwxr-xr-x 1 root    root         4096 Aug  8 07:44 ..

-rw-r--r-- 1 gpadmin gpadmin 103557483 Aug  8 07:58 DataSciencePython-1.0.0-gp4-rhel6-x86_64.gppkg

-rw-r--r-- 1 gpadmin gpadmin 114736878 Aug  8 07:58 DataScienceR-1.0.0-gp4-rhel6-x86_64.gppkg

-rw-r--r-- 1 gpadmin gpadmin   3932160 Aug  8 05:10 madlib-1.12-gp4.3-rhel5-x86_64.tar

-rw-r--r-- 1 gpadmin gpadmin       566 Aug 29  2017 ._madlib-ossv1.12_pv1.9.9_gpdb4.3orca-rhel5-x86_64.gppkg

-rw-r--r-- 1 gpadmin gpadmin   3728292 Aug 29  2017 madlib-ossv1.12_pv1.9.9_gpdb4.3orca-rhel5-x86_64.gppkg

-rw-r--r-- 1 gpadmin gpadmin      1362 Aug 29  2017 ._open_source_license_MADlib_1.12_GA.txt

-rw-r--r-- 1 gpadmin gpadmin    135530 Aug 29  2017 open_source_license_MADlib_1.12_GA.txt

-rw-r--r-- 1 gpadmin gpadmin  39640735 Aug  8 07:51 plr-2.3.1-GPDB4.3-rhel6-x86_64.gppkg

-rw-r--r-- 1 gpadmin gpadmin       594 Aug 29  2017 ._ReleaseNotes.txt

-rw-r--r-- 1 gpadmin gpadmin     51900 Aug 29  2017 ReleaseNotes.txt

 




4-4. DataSciencePython
설치하기 



-bash-4.1$ gppkg -i DataSciencePython-1.0.0-gp4-rhel6-x86_64.gppkg

20180808:08:00:58:007333 gppkg:4e6b947be0d6:gpadmin-[INFO]:-Starting gppkg with args: -i DataSciencePython-1.0.0-gp4-rhel6-x86_64.gppkg

20180808:08:00:59:007333 gppkg:4e6b947be0d6:gpadmin-[INFO]:-Installing package DataSciencePython-1.0.0-gp4-rhel6-x86_64.gppkg

20180808:08:00:59:007333 gppkg:4e6b947be0d6:gpadmin-[INFO]:-Validating rpm installation cmdStr='rpm --test -i /usr/local/greenplum-db-4.3.7.1/.tmp/DataSciencePython-1.0-0.x86_64.rpm --dbpath /usr/local/greenplum-db-4.3.7.1/share/packages/database --prefix /usr/local/greenplum-db-4.3.7.1'

20180808:08:00:59:007333 gppkg:4e6b947be0d6:gpadmin-[INFO]:-SQLITE3 Installed

20180808:08:01:00:007333 gppkg:4e6b947be0d6:gpadmin-[INFO]:-TK Not installed

20180808:08:01:00:007333 gppkg:4e6b947be0d6:gpadmin-[INFO]:-TCL Not installed

20180808:08:01:00:007333 gppkg:4e6b947be0d6:gpadmin-[INFO]:-Installing DataSciencePython-1.0.0-gp4-rhel6-x86_64.gppkg locally

20180808:08:01:00:007333 gppkg:4e6b947be0d6:gpadmin-[INFO]:-Validating rpm installation cmdStr='rpm --test -i /usr/local/greenplum-db-4.3.7.1/.tmp/DataSciencePython-1.0-0.x86_64.rpm --dbpath /usr/local/greenplum-db-4.3.7.1/share/packages/database --prefix /usr/local/greenplum-db-4.3.7.1'

20180808:08:01:01:007333 gppkg:4e6b947be0d6:gpadmin-[INFO]:-Installing rpms cmdStr='rpm -i /usr/local/greenplum-db-4.3.7.1/.tmp/DataSciencePython-1.0-0.x86_64.rpm --dbpath /usr/local/greenplum-db-4.3.7.1/share/packages/database --prefix=/usr/local/greenplum-db-4.3.7.1'

20180808:08:01:14:007333 gppkg:4e6b947be0d6:gpadmin-[INFO]:-Completed local installation of DataSciencePython-1.0.0-gp4-rhel6-x86_64.gppkg.

20180808:08:01:14:007333 gppkg:4e6b947be0d6:gpadmin-[INFO]:-Please source your $GPHOME/greenplum_path.sh file and restart the database.

20180808:08:01:14:007333 gppkg:4e6b947be0d6:gpadmin-[INFO]:-DataSciencePython-1.0.0-gp4-rhel6-x86_64.gppkg successfully installed.

 




4-5. DataScienceR
설치하기 



-bash-4.1$ gppkg -i DataScienceR-1.0.0-gp4-rhel6-x86_64.gppkg

20180808:08:01:48:007393 gppkg:4e6b947be0d6:gpadmin-[INFO]:-Starting gppkg with args: -i DataScienceR-1.0.0-gp4-rhel6-x86_64.gppkg

20180808:08:01:48:007393 gppkg:4e6b947be0d6:gpadmin-[INFO]:-Installing package DataScienceR-1.0.0-gp4-rhel6-x86_64.gppkg

20180808:08:01:49:007393 gppkg:4e6b947be0d6:gpadmin-[INFO]:-Validating rpm installation cmdStr='rpm --test -i /usr/local/greenplum-db-4.3.7.1/.tmp/DataScienceR-1.0-0.x86_64.rpm --dbpath /usr/local/greenplum-db-4.3.7.1/share/packages/database --prefix /usr/local/greenplum-db-4.3.7.1'

20180808:08:01:49:007393 gppkg:4e6b947be0d6:gpadmin-[INFO]:-Installing DataScienceR-1.0.0-gp4-rhel6-x86_64.gppkg locally

20180808:08:01:50:007393 gppkg:4e6b947be0d6:gpadmin-[INFO]:-Validating rpm installation cmdStr='rpm --test -i /usr/local/greenplum-db-4.3.7.1/.tmp/DataScienceR-1.0-0.x86_64.rpm --dbpath /usr/local/greenplum-db-4.3.7.1/share/packages/database --prefix /usr/local/greenplum-db-4.3.7.1'

20180808:08:01:50:007393 gppkg:4e6b947be0d6:gpadmin-[INFO]:-Installing rpms cmdStr='rpm -i /usr/local/greenplum-db-4.3.7.1/.tmp/DataScienceR-1.0-0.x86_64.rpm --dbpath /usr/local/greenplum-db-4.3.7.1/share/packages/database --prefix=/usr/local/greenplum-db-4.3.7.1'

20180808:08:02:05:007393 gppkg:4e6b947be0d6:gpadmin-[INFO]:-Completed local installation of DataScienceR-1.0.0-gp4-rhel6-x86_64.gppkg.

20180808:08:02:05:007393 gppkg:4e6b947be0d6:gpadmin-[INFO]:-Please source your $GPHOME/greenplum_path.sh file and restart the database.

20180808:08:02:05:007393 gppkg:4e6b947be0d6:gpadmin-[INFO]:-DataScienceR-1.0.0-gp4-rhel6-x86_64.gppkg successfully installed.

 




4-6. source path
설정 


-bash-4.1$ source $GPHOME/greenplum_path.sh




4-7. GPDB stop
 



-bash-4.1$ gpstop -af

20180808:08:02:18:007430 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Starting gpstop with args: -af

20180808:08:02:18:007430 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Gathering information and validating the environment...

20180808:08:02:18:007430 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Obtaining Greenplum Master catalog information

20180808:08:02:18:007430 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Obtaining Segment details from master...

20180808:08:02:18:007430 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Greenplum Version: 'postgres (Greenplum Database) 4.3.7.1 build 1'

20180808:08:02:18:007430 gpstop:4e6b947be0d6:gpadmin-[INFO]:-There are 0 connections to the database

20180808:08:02:18:007430 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Commencing Master instance shutdown with mode='fast'

20180808:08:02:18:007430 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Master host=72ba20be3774

20180808:08:02:18:007430 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Detected 0 connections to database

20180808:08:02:18:007430 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Using standard WAIT mode of 120 seconds

20180808:08:02:18:007430 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Commencing Master instance shutdown with mode=fast

20180808:08:02:18:007430 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Master segment instance directory=/gpdata/master/gpseg-1

20180808:08:02:19:007430 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Attempting forceful termination of any leftover master process

20180808:08:02:20:007430 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Terminating processes for segment /gpdata/master/gpseg-1

20180808:08:02:20:007430 gpstop:4e6b947be0d6:gpadmin-[INFO]:-No standby master host configured

20180808:08:02:20:007430 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Commencing parallel segment instance shutdown, please wait...

20180808:08:02:20:007430 gpstop:4e6b947be0d6:gpadmin-[INFO]:-0.00% of jobs completed

20180808:08:02:30:007430 gpstop:4e6b947be0d6:gpadmin-[INFO]:-100.00% of jobs completed

20180808:08:02:30:007430 gpstop:4e6b947be0d6:gpadmin-[INFO]:-----------------------------------------------------

20180808:08:02:30:007430 gpstop:4e6b947be0d6:gpadmin-[INFO]:-   Segments stopped successfully      = 2

20180808:08:02:30:007430 gpstop:4e6b947be0d6:gpadmin-[INFO]:-   Segments with errors during stop   = 0

20180808:08:02:30:007430 gpstop:4e6b947be0d6:gpadmin-[INFO]:-----------------------------------------------------

20180808:08:02:30:007430 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Successfully shutdown 2 of 2 segment instances

20180808:08:02:30:007430 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Database successfully shutdown with no errors reported

20180808:08:02:30:007430 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Cleaning up leftover gpmmon process

20180808:08:02:30:007430 gpstop:4e6b947be0d6:gpadmin-[INFO]:-No leftover gpmmon process found

20180808:08:02:30:007430 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Cleaning up leftover gpsmon processes

20180808:08:02:30:007430 gpstop:4e6b947be0d6:gpadmin-[INFO]:-No leftover gpsmon processes on some hosts. not attempting forceful termination on these hosts

20180808:08:02:30:007430 gpstop:4e6b947be0d6:gpadmin-[INFO]:-Cleaning up leftover shared memory

 




4-8. GPDB restart
 



-bash-4.1$ gpstart -a

20180808:08:02:39:007584 gpstart:4e6b947be0d6:gpadmin-[INFO]:-Starting gpstart with args: -a

20180808:08:02:39:007584 gpstart:4e6b947be0d6:gpadmin-[INFO]:-Gathering information and validating the environment...

20180808:08:02:39:007584 gpstart:4e6b947be0d6:gpadmin-[INFO]:-Greenplum Binary Version: 'postgres (Greenplum Database) 4.3.7.1 build 1'

20180808:08:02:39:007584 gpstart:4e6b947be0d6:gpadmin-[INFO]:-Greenplum Catalog Version: '201310150'

20180808:08:02:39:007584 gpstart:4e6b947be0d6:gpadmin-[INFO]:-Starting Master instance in admin mode

20180808:08:02:40:007584 gpstart:4e6b947be0d6:gpadmin-[INFO]:-Obtaining Greenplum Master catalog information

20180808:08:02:40:007584 gpstart:4e6b947be0d6:gpadmin-[INFO]:-Obtaining Segment details from master...

20180808:08:02:40:007584 gpstart:4e6b947be0d6:gpadmin-[INFO]:-Setting new master era

20180808:08:02:40:007584 gpstart:4e6b947be0d6:gpadmin-[INFO]:-Master Started...

20180808:08:02:40:007584 gpstart:4e6b947be0d6:gpadmin-[INFO]:-Shutting down master

20180808:08:02:42:007584 gpstart:4e6b947be0d6:gpadmin-[INFO]:-Commencing parallel segment instance startup, please wait...

..

20180808:08:02:44:007584 gpstart:4e6b947be0d6:gpadmin-[INFO]:-Process results...

20180808:08:02:44:007584 gpstart:4e6b947be0d6:gpadmin-[INFO]:-----------------------------------------------------

20180808:08:02:44:007584 gpstart:4e6b947be0d6:gpadmin-[INFO]:-   Successful segment starts                                            = 2

20180808:08:02:44:007584 gpstart:4e6b947be0d6:gpadmin-[INFO]:-   Failed segment starts                                                = 0

20180808:08:02:44:007584 gpstart:4e6b947be0d6:gpadmin-[INFO]:-   Skipped segment starts (segments are marked down in configuration)   = 0

20180808:08:02:44:007584 gpstart:4e6b947be0d6:gpadmin-[INFO]:-----------------------------------------------------

20180808:08:02:44:007584 gpstart:4e6b947be0d6:gpadmin-[INFO]:-

20180808:08:02:44:007584 gpstart:4e6b947be0d6:gpadmin-[INFO]:-Successfully started 2 of 2 segment instances

20180808:08:02:44:007584 gpstart:4e6b947be0d6:gpadmin-[INFO]:-----------------------------------------------------

20180808:08:02:44:007584 gpstart:4e6b947be0d6:gpadmin-[INFO]:-Starting Master instance 72ba20be3774 directory /gpdata/master/gpseg-1

20180808:08:02:45:007584 gpstart:4e6b947be0d6:gpadmin-[INFO]:-Command pg_ctl reports Master 72ba20be3774 instance active

20180808:08:02:45:007584 gpstart:4e6b947be0d6:gpadmin-[INFO]:-No standby master configured.  skipping...

20180808:08:02:45:007584 gpstart:4e6b947be0d6:gpadmin-[INFO]:-Database successfully started

-bash-4.1$

-bash-4.1$

 



 

5. Docker 이미지 만들고, Docker Hub에 올리기

 

5-1. Docker 이미지 만들고, 생성 여부 확인하기



 # Docker 이미지 만들기 : $ docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]


ihongdon-ui-MacBook-Pro:~ ihongdon$ docker commit \

-a "pivotal-data-science-holee" \

-m "GPDB 4.37 with MADlib, PL/R, PL/Python" \

gpdb \

gpdb-analytics:first

sha256:c1450e5e5a58f0518ce747a408846968b3a8d2746e6a147c1a3d8ce2910dfff1

ihongdon-ui-MacBook-Pro:~ ihongdon$

ihongdon-ui-MacBook-Pro:~ ihongdon$ docker images

REPOSITORY                         TAG                 IMAGE ID            CREATED             SIZE

gpdb-analytics                     first               c1450e5e5a58        3 minutes ago       2.83GB

centos                             7                   d123f4e55e12        9 months ago        197MB

pivotaldata/gpdb-base              latest              bfe4e63b8e81        2 years ago         1.17GB

ihongdon-ui-MacBook-Pro:~ ihongdon$

 


 

 

5-2. Docker ImageTag 추가 후 Docker Hub에 올리기(push)



 # Tag 추가 : $ docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]


ihongdon-ui-MacBook-Pro:~ ihongdon$ docker tag gpdb-analytics:first hdlee2u/gpdb-analytics:latest

ihongdon-ui-MacBook-Pro:~ ihongdon$

ihongdon-ui-MacBook-Pro:~ ihongdon$ docker images

REPOSITORY                         TAG                 IMAGE ID            CREATED             SIZE

hdlee2u/gpdb-analytics             latest               c1450e5e5a58        About an hour ago   2.83GB

gpdb-analytics                     first               c1450e5e5a58        About an hour ago   2.83GB

centos                             7                   d123f4e55e12        9 months ago        197MB

pivotaldata/gpdb-base              latest              bfe4e63b8e81        2 years ago         1.17GB

 

# Docker Hub 로그인

ihongdon-ui-MacBook-Pro:~ ihongdon$ docker login

Authenticating with existing credentials...

Login Succeeded

 



 # Docker Hub에 도커 이미지 올리기 : $ docker push [OPTIONS] NAME[:TAG]


ihongdon-ui-MacBook-Pro:~ ihongdon$ docker push hdlee2u/gpdb-analytics:latest

The push refers to repository [docker.io/hdlee2u/gpdb-analytics]

e603ef714b8e: Pushing [========>                                          ]  275.1MB/1.663GB

8c65eead2327: Mounted from hdlee2u/gpdb-base

516e5ab465c7: Mounted from hdlee2u/gpdb-base

5f70bf18a086: Mounted from hdlee2u/gpdb-base

69bd93b9db4e: Mounted from hdlee2u/gpdb-base





[ https://hub.docker.com/r/hdlee2u/gpdb-analytics/ 에 gpdb-analytics 도커 이미지 올라간 모습 ]




다음번 포스팅에서는 Docker Hub에서 gpdb-ds 도커 이미지를 내려 받아서 사용할 수 있는 방법에 대해서 소개하겠습니다. 


많은 도움이 되었기를 바랍니다. 



728x90
반응형
Posted by Rfriend
,

이번 포스팅에서는 Greenplum Database (Data Platform)에 대해서 소개하겠습니다. 


세상에는 여러 개의 Database가 존재합니다.  그중에서도 Greenplum Database (줄여서 GPDB라고도 부름)은 MPP(Massively Parallel Processing) 아키텍처 기반의 Open Source RDBMS 에 해당합니다. 


Greenplum Database Community 홈페이지에 가보면 Greenplum DB를 "세계 최초의 오픈소스 & MPP 데이터 플랫폼 (The World's First Open-Source & Massively Parallel Data Platform)" 이라고 소개하고 있습니다. 



[ Greenplum Database, "The World's First Open-Source & Massively Parallel Data Platform" ]




Greenplum DB (이하 GPDB)는 2003년 미국 캘리포니아 산호세에서 처음 시작해서 2010년에 EMC에 인수되었습니다. 그리고 2012년부터는 Pivotal Greenplum Database로 이름이 바뀌었으며, 기업용의 상용SW로 Pivotal Software에서 판매, 유지보수 서비스를 하고 있습니다. 그리고 현재까지 오픈소스 커뮤니티와 Pivotal에서 Agile방법론에 입각해서 지속적으로 업그레이드를 하고 있습니다. 


왜 수십~수백 테라 바이트, 수 페타바이트 급의 빅데이터 분석에 MPP 아키텍처인지가 필요한지에 대한 이해를 돕기 위해서, SMP(Symmetric Multi-Processing) 와 MPP(Massively Prarallel Processing) 아키텍처에 대해서 간략히 설명드리겠습니다. 



[ SMP(Symmetric Multi-Processing) vs. MPP(Massively Parallel Processing) ]





SMP(Symmetric Multi-Processing) 아키텍처는 보통 "Shard Everything Architecture"라고도 하는데요, 모든 CPU가 하나의 메모리와 디스크를 사용합니다. 따라서 관리가 편리한 장점이 있는 반면에 관리/분석해야하는 데이터 용량이 커지면 Scale Up 하는데 한계를 가지게 됩니다. 


반면에 MPP(Massively Parallel Processing) 아키텍처는 "Shared Nothing Architecture"라고도 하는데요, 데이터가 여러개의 디스크에 분산되어 저장이 되며, 여러개의 CPU가 각각 메모리와 디스크를 할당받아 이용을 하게 됨에 따라 분산병렬처리가 가능하게 됩니다. 데이터 용량을 늘리려면 디스크, 메모리, CPU를 옆으로 계속 확장하여 네트워크로 연결을 해주는 Scale Out 방식을 취하면 되어 이론적으로는 계속 확장을 할 수 있습니다. 그리고 분산병렬처리를 하게 됨에 따라 노드 수에 비례하여 연산의 속도가 빨라집니다. 단점으로는 SMP 아키텍처 대비 상대적으로 복잡하고 관리가 어려우며 비용이 비싸다는 점입니다. 


Greenplum Database는 PostgreSQL 기반의 MPP 아키텍처의 장점을 가지면서, Proprietary Commercial DB들 대비 오픈소스로서 상대적으로 TCO(Total Cost of Ownership)이 낮고 혁신의 속도가 빠르다는 장점이 있습니다. 그리고 Pivotal Software에서 기업용으로 판매, 유지보수 지원을 해주므로 기업에서 도입하여 사용하기에도 문제가 없다고 하겠습니다. 


Pivotal은 Agile S/W 개발 방법론과 DevOps라는 개념을 처음으로 주창했던 기업(Pivotal Labs)이며, PCF(Pivotal Cloud Foundry)라는 Cloud Platform도 개발, 판매하는 소프트웨어 개발회사입니다. 올해 2018년 4월 달에 나스닥에 상장하기도 하였습니다.  Pivotal은 소프트웨어 회사 중에서도 가장 선도적이고 적극적으로 오픈 소스 철학을 지지하고 커미터로 참여하고 있는 기업입니다. 



[ Pivotal Greenplum and Open Source Eco. ]



Kafka, Spring Cloud Data Flow, RabbitMQ, redis, GemFire 등을 사용하여 실시간 데이터(Fast Data)를 수집/처리하는데요, Greenplum DB와 연동하여 데이터를 수집/저장할 수 있습니다. 


Greenplum DB는 또한 Cloudera, Hortonworks, MapR 등의 하둡 플랫폼과도 전용 connector로 연동하여 하둡 파일 시스템 내의 대용량 데이터를 분산 병렬로 데이터를 매우 빠르게 로딩할 수도 있습니다. 



[ MPP(Massively Parallel Processing) 기반의 Greenplum 아키텍처 ]





특히, 초대용량 데이터를 분석하는 데이터 분석가, 데이터 과학자의 입장에서는 SQL로 데이터 전처리, 집계, 분석과 함께 SQL로 빅데이터 기계학습을 할 수 있는 MADlib, R과 Python의 다양한 통계, 기계학습 라이브러리를 Greenplum DB에 설치하여 대용량 데이터를 분산병렬로 분석, 모델 학습, 스코어링 등이 가능합니다. R, Python, Java, C, Perl 등의 프로그래밍 언어를 가지고 DB 내에서 분산병렬로 사용할 수 있는 PL/x(Procedutal Language) 기능도 지원함에 따라 복잡한 사용자 정의 함수를 프로그래밍하여 사용할 수 있는 엄청난 매력이 있습니다. 


보통 R이나 Python, MATLAB, SAS 등으로 데이터를 분석할 때 DB로 부터 데이터를 내려받고, 다시 로딩하고하고, 분석 결과를 다시 DB로 옮기고 하는데 엄청나게 많은 시간이 소요되며, 시스템 운영 상에도 복잡성을 높여 관리의 어려움을 가중시키곤 합니다. 그리고 R, Python 등을 사용하려면 분석 컴퓨터의 디스크, 메모리가 감당할 수 있는 수준의 데이터 양만 가지고 분석을 할 수 있으므로 보통 샘플링한 데이터를 가지고 분석을 하게 됨에 따라 분석의 정확도(과적합 위험)를 제약하는 한계도 가집니다. 


그런데 Greenplum Database를 사용하면 In-Database 에서 데이터의 이동 없이 초대용량 데이터를 분산병렬처리로 분석, 기계학습할 수 있습니다. 



[ Greenplum : In-Database 정형 & 비정형 데이터 통합 분석 플랫폼 ]




또한 Greenplum DB는 정형데이터 뿐만 아니라, 텍스트 데이터(w/ Solr 기반 GPText), 지리데이터(w/ PostGIS), 그래프데이터(MADlib) 분석도 하나의 DB 안에서 정형 데이터와 연계하여 통합 분석, 기계학습이 모두 가능함에 따라 분석의 자유도와 그동안은 찾을 수 없었던 새로운 인사이트를 도출할 수 있는 매우 강력한 차세대 분석 플랫폼입니다. 


Greenplum DB는 On-premise 뿐만 아니라 가상화 환경 위에 Private Cloud, Public Cloud (Amazon AWS, Google Cloud, Microsoft Azure) 위에서도 구동 가능합니다. (도커 컨테이너 기반 Greenplum 은 '18년 하반기)



[ On-premise, 가상화 환경, 클라우드 환경에서 모두 구동되는 Greenplum ]





초대용량의 정형 & 비정형 데이터를 망라해서 통계분석, 기계학습을 필요로 하는 기업, 데이터 과학자, 데이터 엔지니어라면 Greenplum DB는 첫번째로 꼽을 수 있는 차세대 분석 플랫폼이라고 할 수 있습니다. 


다음번 포스팅에서는 Greenplum DB에 MADlib, PL/R, PL/Python 을 설치하여 Docker Image로 만들어서 Docker Hub에 올리는 방법을 소개하겠습니다. 


많은 도움이 되었기를 바랍니다. 


[Reference site]

(1) https://pivotal.io/

(2) https://network.pivotal.io/

(3) https://greenplum.org/

(4) https://github.com/greenplum-db

(5) http://madlib.apache.org/

(6) https://gptext.docs.pivotal.io/

(7) Greenplum Database: The First Open Source Data Warehouse (https://www.youtube.com/watch?v=E11aE38YoQ0)


마지막으로 Pivotal의 Greenplum DB product manager인 Ivan Novick의 유튜브 발표 자료 공유합니다. 



728x90
반응형
Posted by Rfriend
,

이번 포스팅에서는 R로 쇼핑몰 웹사이트의 텍스트를 가져와서 최저가 Top 10 리스트를 선별해서 DataFrame으로 만든 후에, 이를 엑셀로 내보내기를 해보겠습니다. 


아래 코드는 제 블로그에 질문을 남겨주신 분께서 거의 다 짜셨구요, 저는 엑셀로 내보내는 부분의 에러를 바로 잡는 방법을 안내해드렸었습니다. 


textreadr, rvest, xlsx 등의 R 패키지와 사용법에 대해서 블로그의 본문에 정식으로 한번 더 소개해드리면 더욱 많은 분들께서 검색해서 이용하시기에 편리할 듯 해서 본문에 다시 한번 포스팅합니다. 



1. R 패키지 설치 및 로딩



# clear all

rm(list=ls())


# install and load libries

install.packages("textreadr")

install.packages("rvest")

install.packages("xlsx")


library(textreadr)

library(rvest)

library(xlsx)

 




2. 각 제품별로 엑셀 sheet 를 분리해서 최저가 Top 10 업체 결과 내보내기



urlbase <- "https://search.shopping.naver.com/search/all.nhn?query="

low <- c("에어팟","코카콜라","건전지","삼다수")


df <- data.frame()


# for loop statement

for (i in low){

  url <- paste(urlbase, i ,"&cat_id=&frm=NVSHATC",sep="")

  nv <- read_html(url, encoding = "UTF-8")

  st <- html_nodes(nv, '.mall_name') %>% html_text()

  st <- st[1:10]

  price3 <- html_nodes(nv, '._lowPriceByMall') %>% html_nodes('.price') %>% html_text()

  price3 <- gsub('최저가','',price3)

  price3 <- price3[1:10] # 최저가 Top 10

  df <- data.frame(가게명=st, 가격=price3)

  

  # append df to df_all

  df <- rbind(df, data.frame(가게명=url, 가격="r"))

  

  # adding sheetName

  write.xlsx(df, file="C:/Users/admin/Documents/df_sheet.xlsx", 

             sheetName=i, # excel sheet per each product or brand

             col.names=TRUE

             append=TRUE)

 

  # check progress

  print(paste0(i, " has been completed."))

}

 



위의 코드를 실행한 엑셀 파일은 아래와 같이 각 sheet 별로 제품이 구분이 되어있습니다. 






3. 모든 제품에 대해서 하나의 엑셀 sheet에 모두 모아서 최저가 Top 10 결과 내보내기



urlbase <- "https://search.shopping.naver.com/search/all.nhn?query="

low <- c("에어팟","코카콜라","건전지","삼다수")


df_all <- data.frame()


# for loop statement

for (i in low){

  url <- paste(urlbase, i ,"&cat_id=&frm=NVSHATC",sep="")

  nv <- read_html(url, encoding = "UTF-8")

  st <- html_nodes(nv, '.mall_name') %>% html_text()

  st <- st[1:10]

  price3 <- html_nodes(nv, '._lowPriceByMall') %>% html_nodes('.price') %>% html_text()

  price3 <- gsub('최저가','',price3)

  price3 <- price3[1:10]

  df <- data.frame(item=i, 가게명=st, 가격=price3)

  

  # append url info to df_all

  df <- rbind(df, data.frame(item=i, 가게명=url, 가격="r"))

  

  # combining df to df_all one by one

  df_all <- rbind(df_all, df)

  

  # check progress

  print(paste0(i, " has been completed."))

}


# exporting df_all to excel

write.xlsx(df_all, 

           file="C:/Users/admin/Documents/df_all.xlsx", 

           col.names=TRUE)

 




위의 코드를 실행한 엑셀 파일 결과는 아래와 같이 하나의 sheet에 각 제품(item) 변수로 구분이 되어서 한꺼번에 모아서 엑셀로 내보내기가 되었음을 알 수 있습니다. 





많은 도움이 되었기를 바랍니다. 

728x90
반응형
Posted by Rfriend
,

이번 포스팅에서는 터미널에서 사용할 수 있는 Git 기본 명령어,  Branch 만들기 합치기, 원격 repository에 push 하고 pull 하는 Git 명령어 사용법을 알아보겠습니다. 



  1. Git 기본 사용법


  • git init : repository 초기화


ihongdon-ui-MacBook-Pro:GitHub ihongdon$ mkdir git-test

ihongdon-ui-MacBook-Pro:GitHub ihongdon$ cd git-test

ihongdon-ui-MacBook-Pro:git-test ihongdon$ pwd

/Users/ihongdon/Documents/GitHub/git-test


ihongdon-ui-MacBook-Pro:git-test ihongdon$ git init

Initialized empty Git repository in /Users/ihongdon/Documents/GitHub/git-test/.git/

 




  • git status : repository 상태 확인


ihongdon-ui-MacBook-Pro:git-test ihongdon$ git status

On branch master

No commits yet

nothing to commit (create/copy files and use "git add" to track)

 




  • README.md 파일 생성


ihongdon-ui-MacBook-Pro:git-test ihongdon$ touch READMD.md

ihongdon-ui-MacBook-Pro:git-test ihongdon$ git status

On branch master


No commits yet


Untracked files:

  (use "git add <file>..." to include in what will be committed)


READMD.md


nothing added to commit but untracked files present (use "git add" to track)

 




  • git add : stage 영역에 파일을 추가하여 git repository에서 파일을 관리하도록 해줌


ihongdon-ui-MacBook-Pro:git-test ihongdon$ git add READMD.md 

ihongdon-ui-MacBook-Pro:git-test ihongdon$ git status

On branch master


No commits yet


Changes to be committed:

  (use "git rm --cached <file>..." to unstage)


new file:   READMD.md

 




  • git commit : repository에 변경 내용을 기록 ( -m : 한줄의 commit 메시지 기록)


ihongdon-ui-MacBook-Pro:git-test ihongdon$ git commit -m "commit of README.md file"

[master (root-commit) d337268] commit of README.md file

 1 file changed, 2 insertions(+)

 create mode 100644 READMD.md

ihongdon-ui-MacBook-Pro:git-test ihongdon$ git status

On branch master

nothing to commit, working tree clean

 




  • git log : repository에 commite된 로그를 확인


ihongdon-ui-MacBook-Pro:git-test ihongdon$ git log

commit d337268ccec9ffcb3a19d6d1ec86304b791ae093 (HEAD -> master)

Author: xxxxxx_xxx <xxxxxx@xxxxx.com>

Date:   Sun Aug 5 16:51:55 2018 +0900


    commit of README.md file

 




  • git log --pretty=short : commit 메시지의 첫 번째 줄만 출력(여러 개의 commit 파악 용이)


ihongdon-ui-MacBook-Pro:git-test ihongdon$ git log --pretty=short

commit d337268ccec9ffcb3a19d6d1ec86304b791ae093 (HEAD -> master)

Author: xxxxxx_xxx <xxxxxx@xxxxx.com>


    commit of README.md file

ihongdon-ui-MacBook-Pro:git-test ihongdon$ 

 




  • git log filename : 선택한 폴더 혹은 파일의 로그만 출력하기


ihongdon-ui-MacBook-Pro:git-test ihongdon$ git log READMD.md 

commit d337268ccec9ffcb3a19d6d1ec86304b791ae093 (HEAD -> master)

Author: xxxxxx_xxx <xxxxxx@xxxxx.com>

Date:   Sun Aug 5 16:51:55 2018 +0900


    commit of README.md file

i-ui-MacBook-Pro:git-test ihongdon$ 

 




  • git log -p filename : 파일의 변경된 내용을 출력하여 확인하기


ihongdon-ui-MacBook-Pro:git-test ihongdon$ git log -p READMD.md 

commit d337268ccec9ffcb3a19d6d1ec86304b791ae093 (HEAD -> master)

Author: xxxxxx_xxx <xxxxxx@xxxxx.com>

Date:   Sun Aug 5 16:51:55 2018 +0900


    commit of README.md file


diff --git a/READMD.md b/READMD.md

new file mode 100644

index 0000000..c90fe08

--- /dev/null

+++ b/READMD.md

@@ -0,0 +1,2 @@

+This is a git-test repository. 

+I'm writing README.md file as a test.

ihongdon-ui-MacBook-Pro:git-test ihongdon$ 

 




  • git diff : working tree, stage 영역, 최신 commit 사이의 변경 내역을 확인 
    => working tree와 stage 영역의 차이를 확인


git diffihongdon-ui-MacBook-Pro:git-test ihongdon$ git diff

diff --git a/READMD.md b/READMD.md

index c90fe08..2424cd6 100644

--- a/READMD.md

+++ b/READMD.md

@@ -1,2 +1,6 @@

+# Git Tutorial

+

+## version 1

+

 This is a git-test repository. 

 I'm writing README.md file as a test.

ihongdon-ui-MacBook-Pro:git-test ihongdon$

 




  • git add 명령어로 stage 영역에 README.md 파일을 추가한 후 git diff 명령어를 사용하면 working tree와 stage 영역 사이의 차이가 없으므로 아무것도 표시되지 않습니다. 


ihongdon-ui-MacBook-Pro:git-test ihongdon$ git add READMD.md 

ihongdon-ui-MacBook-Pro:git-test ihongdon$ git diff

ihongdon-ui-MacBook-Pro:git-test ihongdon$ # 아무것도 표시되지 않음

 




  • git diff HEAD : working tree에서 최신의 변경 부분을 확인하기 (HEAD는 현재 작업하고 있는 branch의 최신 commit을 참조하는 포인터)


ihongdon-ui-MacBook-Pro:git-test ihongdon$ git diff HEAD

diff --git a/READMD.md b/READMD.md

index c90fe08..2424cd6 100644

--- a/READMD.md

+++ b/READMD.md

@@ -1,2 +1,6 @@

+# Git Tutorial

+

+## version 1

+

 This is a git-test repository. 

 I'm writing README.md file as a test.

ihongdon-ui-MacBook-Pro:git-test ihongdon$ 

 




  • git commit -m : 수정사항 commit


ihongdon-ui-MacBook-Pro:git-test ihongdon$ git commit -m "Add title and version"

[master ea87d54] Add title and version

 1 file changed, 4 insertions(+)

ihongdon-ui-MacBook-Pro:git-test ihongdon$ 

 




  • git log : commit 확인


ihongdon-ui-MacBook-Pro:git-test ihongdon$ git log

commit ea87d546d8649ea000d071727c0b14e870bc714e (HEAD -> master)

Author: xxxxxx_xxx <xxxxxx@xxxxx.com>

Date:   Sun Aug 5 17:30:31 2018 +0900


    Add title and version


commit d337268ccec9ffcb3a19d6d1ec86304b791ae093

Author: xxxxxx_xxx <xxxxxx@xxxxx.com>

Date:   Sun Aug 5 16:51:55 2018 +0900


    commit of README.md file

ihongdon-ui-MacBook-Pro:git-test ihongdon$ 

 




  2. Branch 생성하고 합치기


  • git branch : 현재 사용하고 있는 branch 확인 하기


ihongdon-ui-MacBook-Pro:git-test ihongdon$ git branch

* master

 




  • git checkout -b branch_name : 새로운 branch를 만들고, 새로운 branch로 변경하기


ihongdon-ui-MacBook-Pro:git-test ihongdon$ git checkout -b readme-edit-v2

Switched to a new branch 'readme-edit-v2'


ihongdon-ui-MacBook-Pro:git-test ihongdon$ git branch # current branch check

  master

* readme-edit-v2

 





  • 'readme-edit-v2' branch 에서 date 추가하고 commit 하기


ihongdon-ui-MacBook-Pro:git-test ihongdon$ vi READMD.md 

ihongdon-ui-MacBook-Pro:git-test ihongdon$ cat READMD.md 

# Git Tutorial


## version 1


### date : as of 5th Aug.


This is a git-test repository. 

I'm writing README.md file as a test.


ihongdon-ui-MacBook-Pro:git-test ihongdon$ git add READMD.md 

ihongdon-ui-MacBook-Pro:git-test ihongdon$ git commit -m "Add date"

[readme-edit-v2 8254c2e] Add date

 1 file changed, 2 insertions(+)

ihongdon-ui-MacBook-Pro:git-test ihongdon$ git log

commit 8254c2e24c83e0e3f8e843228ca84fbba8998e54 (HEAD -> readme-edit-v2)

Author: xxxxxx_xxx <xxxxxx@xxxxx.com>

Date:   Sun Aug 5 19:30:04 2018 +0900


    Add date


commit ea87d546d8649ea000d071727c0b14e870bc714e (master)

Author: xxxxxx_xxx <xxxxxx@xxxxx.com>

Date:   Sun Aug 5 17:30:31 2018 +0900


    Add title and version


commit d337268ccec9ffcb3a19d6d1ec86304b791ae093

Author: xxxxxx_xxx <xxxxxx@xxxxx.com>

Date:   Sun Aug 5 16:51:55 2018 +0900


    commit of README.md file

ihongdon-ui-MacBook-Pro:git-test ihongdon$ 

 




  • git checkout master : master branch로 변경


ihongdon-ui-MacBook-Pro:git-test ihongdon$ git checkout master

Switched to branch 'master'

 




>> 아직 master branch에 'readme-edit-v2' branch의 변경사항이 반영되지 않았음

 

ihongdon-ui-MacBook-Pro:git-test ihongdon$ cat READMD.md 

# Git Tutorial


## version 1


This is a git-test repository. 

I'm writing README.md file as a test.

ihongdon-ui-MacBook-Pro:git-test ihongdon$





  • git merge --no-f topic_branch_name : Topic branch를 master branch에 통합하기


ihongdon-ui-MacBook-Pro:git-test ihongdon$ git merge --no-ff readme-edit-v2


아래와 같은 에디터가 나타납니다. 


hint: Waiting for your editor to close the file... 

Merge branch 'readme-edit-v2'

  

# Please enter a commit message to explain why this merge is necessary,

# especially if it merges an updated upstream into a topic branch.

#

# Lines starting with '#' will be ignored, and an empty message aborts

# the commit.



에디터를 저장하고 종료(esc 후 :wq!)하면 아래와 같은 메시지가 나옵니다. 


Merge made by the 'recursive' strategy.

 READMD.md | 2 ++

 1 file changed, 2 insertions(+)

ihongdon-ui-MacBook-Pro:git-test ihongdon$ 

 




>> date 통합 확인



ihongdon-ui-MacBook-Pro:git-test ihongdon$ cat READMD.md 

# Git Tutorial


## version 1


### date : as of 5th Aug.


This is a git-test repository. 

I'm writing README.md file as a test.

ihongdon-ui-MacBook-Pro:git-test ihongdon$ 

 




  • git log --graph : branch 분기 또는 통합을 그래프로 표시


ihongdon-ui-MacBook-Pro:git-test ihongdon$ git log --graph

*   commit f36bf439021e2220a56c01e6bf7e20ea897c8598 (HEAD -> master)

|\  Merge: ea87d54 8254c2e

| | Author: xxxxxx_xxx <xxxxxx@xxxxx.com>

| | Date:   Sun Aug 5 19:55:05 2018 +0900

| | 

| |     Merge branch 'readme-edit-v2'

| | 

| * commit 8254c2e24c83e0e3f8e843228ca84fbba8998e54 (readme-edit-v2)

|/  Author: xxxxxx_xxx <xxxxxx@xxxxx.com>

|   Date:   Sun Aug 5 19:30:04 2018 +0900

|   

|       Add date

* commit ea87d546d8649ea000d071727c0b14e870bc714e

| Author: xxxxxx_xxx <xxxxxx@xxxxx.com>

| Date:   Sun Aug 5 17:30:31 2018 +0900

|     Add title and version

* commit d337268ccec9ffcb3a19d6d1ec86304b791ae093

  Author: xxxxxx_xxx <xxxxxx@xxxxx.com>

  Date:   Sun Aug 5 16:51:55 2018 +0900

  

      commit of README.md file

ihongdon-ui-MacBook-Pro:git-test ihongdon$ 

 




######################################################################


  • git reset : 과거 상태로 되돌리기 (다른 위치의 repository에는 영향 없음)   
    --> readme-edit-v2 통합하기 이전 상태로 되돌리기


ihongdon-ui-MacBook-Pro:git-test ihongdon$ git reset --hard ea87d546d8649ea000d071727c0b14e870bc714e

HEAD is now at ea87d54 Add title and version

ihongdon-ui-MacBook-Pro:git-test ihongdon$ 

ihongdon-ui-MacBook-Pro:git-test ihongdon$ git branch

* master

  readme-edit-v2

ihongdon-ui-MacBook-Pro:git-test ihongdon$ cat READMD.md 

# Git Tutorial


## version 1


This is a git-test repository. 

I'm writing README.md file as a test.

ihongdon-ui-MacBook-Pro:git-test ihongdon$ 

 







  • git checkout -b readme-edit-v3 : readme-edit-v3라는 이름의 새로운 branch 생성


 ihongdon-ui-MacBook-Pro:git-test ihongdon$ git checkout -b readme-edit-v3

Switched to a new branch 'readme-edit-v3'


ihongdon-ui-MacBook-Pro:git-test ihongdon$ vi READMD.md 

ihongdon-ui-MacBook-Pro:git-test ihongdon$ cat READMD.md 

# Git Tutorial


## version 3


### new topic branch readme-edit-v3


This is a git-test repository. 

I'm writing README.md file as a test.





  • git reflog : 현재 repository에서 수행된 모든 commit 로그 확인 하기 
    (vs. git log 명령어는 현재 branch의 로그만 확인 가능)


ihongdon-ui-MacBook-Pro:git-test ihongdon$ git reflog

ea87d54 (HEAD -> readme-edit-v3, master) HEAD@{0}: checkout: moving from master to readme-edit-v3

ea87d54 (HEAD -> readme-edit-v3, master) HEAD@{1}: reset: moving to ea87d546d8649ea000d071727c0b14e870bc714e

f36bf43 HEAD@{2}: merge readme-edit-v2: Merge made by the 'recursive' strategy.

ea87d54 (HEAD -> readme-edit-v3, master) HEAD@{3}: checkout: moving from readme-edit-v2 to master

8254c2e (readme-edit-v2) HEAD@{4}: checkout: moving from master to readme-edit-v2

ea87d54 (HEAD -> readme-edit-v3, master) HEAD@{5}: checkout: moving from readme-edit-v2 to master

8254c2e (readme-edit-v2) HEAD@{6}: commit: Add date

ea87d54 (HEAD -> readme-edit-v3, master) HEAD@{7}: checkout: moving from master to readme-edit-v2

ea87d54 (HEAD -> readme-edit-v3, master) HEAD@{8}: commit: Add title and version

d337268 HEAD@{9}: commit (initial): commit of README.md file

 




  • git reset --hard log_hash : 다시 'readme-edit-v2' 분리 하기 이전 상태로 되돌리기 (reset)


ihongdon-ui-MacBook-Pro:git-test ihongdon$ git checkout master

M READMD.md

Switched to branch 'master'

ihongdon-ui-MacBook-Pro:git-test ihongdon$ git reset --hard f36bf43

HEAD is now at f36bf43 Merge branch 'readme-edit-v2'

ihongdon-ui-MacBook-Pro:git-test ihongdon$ 


ihongdon-ui-MacBook-Pro:git-test ihongdon$ cat READMD.md 

# Git Tutorial


## version 1


### date : as of 5th Aug.


This is a git-test repository. 

I'm writing README.md file as a test.

ihongdon-ui-MacBook-Pro:git-test ihongdon$ 

 




>> git commit  



ihongdon-ui-MacBook-Pro:git-test ihongdon$ vi READMD.md 

ihongdon-ui-MacBook-Pro:git-test ihongdon$ cat READMD.md 

# Git Tutorial

## version 3

## readme-edit-v3

i

ihongdon-ui-MacBook-Pro:git-test ihongdon$ git add READMD.md 

ihongdon-ui-MacBook-Pro:git-test ihongdon$ git commit -m "readme edit version 3"

[readme-edit-v3 59e4132] readme edit version 3

 1 file changed, 2 insertions(+), 2 deletions(-)

ihongdon-ui-MacBook-Pro:git-test ihongdon$ 

 




  • git reflog : 현재 repository에서 수행된 모든 commit 로그 확인 하기


ihongdon-ui-MacBook-Pro:git-test ihongdon$ git reflog

59e4132 (HEAD -> readme-edit-v3) HEAD@{0}: commit: readme edit version 3

ea87d54 HEAD@{1}: checkout: moving from master to readme-edit-v3

f36bf43 (master) HEAD@{2}: reset: moving to f36bf43

ea87d54 HEAD@{3}: checkout: moving from readme-edit-v3 to master

ea87d54 HEAD@{4}: checkout: moving from master to readme-edit-v3

ea87d54 HEAD@{5}: reset: moving to ea87d546d8649ea000d071727c0b14e870bc714e

f36bf43 (master) HEAD@{6}: merge readme-edit-v2: Merge made by the 'recursive' strategy.

ea87d54 HEAD@{7}: checkout: moving from readme-edit-v2 to master

8254c2e (readme-edit-v2) HEAD@{8}: checkout: moving from master to readme-edit-v2

ea87d54 HEAD@{9}: checkout: moving from readme-edit-v2 to master

8254c2e (readme-edit-v2) HEAD@{10}: commit: Add date

ea87d54 HEAD@{11}: checkout: moving from master to readme-edit-v2

ea87d54 HEAD@{12}: commit: Add title and version

d337268 HEAD@{13}: commit (initial): commit of README.md file

ihongdon-ui-MacBook-Pro:git-test ihongdon$ 

 




  • git commit --amend : 직전에 작성했던 commit 메시지 수정


ihongdon-ui-MacBook-Pro:git-test ihongdon$ git commit --amend

hint: Waiting for your editor to close the file... 

Merge branch 'readme-edit-v3'

  

# Please enter the commit message for your changes. Lines starting

# with '#' will be ignored, and an empty message aborts the commit.

#

# Date:      Sun Aug 5 20:26:01 2018 +0900

#

# On branch master

# Changes to be committed:

#       modified:   READMD.md


[master 7b45ed5] amend commit message by using git commit --amend Merge branch 'readme-edit-v3'

 Date: Sun Aug 5 20:26:01 2018 +0900

ihongdon-ui-MacBook-Pro:git-test ihongdon$ 

 




  • git log graph : branch 분기 또는 통합을 그래프로 표시


ihongdon-ui-MacBook-Pro:git-test ihongdon$ git log --graph

*   commit 7b45ed51381013214cddf19e02e4df38b83587e4 (HEAD -> master)

|\  Merge: f36bf43 59e4132

| | Author: xxxxxx_xxx <xxxxxx@xxxxx.com>

| | Date:   Sun Aug 5 20:26:01 2018 +0900

| | 

| |     amend commit message by using git commit --amend

| |     Merge branch 'readme-edit-v3'

| | 

| * commit 59e4132d3928f580c3a26613b83220af04d13540 (readme-edit-v3)

| | Author: xxxxxx_xxx <xxxxxx@xxxxx.com>

| | Date:   Sun Aug 5 20:23:47 2018 +0900

| | 

| |     readme edit version 3

| |   

* |   commit f36bf439021e2220a56c01e6bf7e20ea897c8598

|\ \  Merge: ea87d54 8254c2e

| |/  Author: xxxxxx_xxx <xxxxxx@xxxxx.com>

|/|   Date:   Sun Aug 5 19:55:05 2018 +0900

| |   

| |       Merge branch 'readme-edit-v2'

| | 

| * commit 8254c2e24c83e0e3f8e843228ca84fbba8998e54 (readme-edit-v2)

|/  Author: xxxxxx_xxx <xxxxxx@xxxxx.com>

|   Date:   Sun Aug 5 19:30:04 2018 +0900

|   

|       Add date

* commit ea87d546d8649ea000d071727c0b14e870bc714e

| Author: xxxxxx_xxx <xxxxxx@xxxxx.com>

| Date:   Sun Aug 5 17:30:31 2018 +0900

|     Add title and version

* commit d337268ccec9ffcb3a19d6d1ec86304b791ae093

  Author: xxxxxx_xxx <xxxxxx@xxxxx.com>

  Date:   Sun Aug 5 16:51:55 2018 +0900

  

      commit of README.md file

ihongdon-ui-MacBook-Pro:git-test ihongdon$ 

 




  • git rebase -i HEAD~2 : 코드를 수정하고 commit 한 뒤에, 바로 앞의 commit에 합치기 
    (간단한 오탈자 수정 시 자주 사용)


ihongdon-ui-MacBook-Pro:git-test ihongdon$ git checkout -b readmd-edit-v4

Switched to a new branch 'readmd-edit-v4'

ihongdon-ui-MacBook-Pro:git-test ihongdon$ vi READMD.md 

ihongdon-ui-MacBook-Pro:git-test ihongdon$ cat READMD.md 

# Git Tutorial

## version 3

## readme-edit-v3

## readyou-edit-v4. <- 오탈자


### date : as of 5th Aug.


This is a git-test repository. 

I'm writing README.md file as a test.

ihongdon-ui-MacBook-Pro:git-test ihongdon$ 

ihongdon-ui-MacBook-Pro:git-test ihongdon$ git add READMD.md 

ihongdon-ui-MacBook-Pro:git-test ihongdon$ git commit -m "readme-edit-v4"

[readmd-edit-v4 b2e7b0b] readme-edit-v4

 1 file changed, 1 insertion(+)


ihongdon-ui-MacBook-Pro:git-test ihongdon$ vi READMD.md  # 오탈자 수정함

ihongdon-ui-MacBook-Pro:git-test ihongdon$ git diff

diff --git a/READMD.md b/READMD.md

index 2b9a28f..91bda6a 100644

--- a/READMD.md

+++ b/READMD.md

@@ -1,7 +1,7 @@

 # Git Tutorial

 ## version 3

 ## readme-edit-v3

-## readyou-edit-v4

+## readme-edit-v4

 

 ### date : as of 5th Aug.

 

ihongdon-ui-MacBook-Pro:git-test ihongdon$ git add READMD.md 

ihongdon-ui-MacBook-Pro:git-test ihongdon$ git commit -m "Fix typo"

[readmd-edit-v4 71d869f] Fix typo

 1 file changed, 1 insertion(+), 1 deletion(-)

ihongdon-ui-MacBook-Pro:git-test ihongdon$ 

ihongdon-ui-MacBook-Pro:git-test ihongdon$ git rebase -i HEAD~2


pick b2e7b0b readme-edit-v4

pick 71d869f Fix typo


# Rebase 7b45ed5..71d869f onto 7b45ed5 (2 commands)

#

# Commands:

# p, pick <commit> = use commit

# r, reword <commit> = use commit, but edit the commit message

# e, edit <commit> = use commit, but stop for amending

# s, squash <commit> = use commit, but meld into previous commit

# f, fixup <commit> = like "squash", but discard this commit's log message

# x, exec <command> = run command (the rest of the line) using shell

# d, drop <commit> = remove commit

# l, label <label> = label current HEAD with a name

# t, reset <label> = reset HEAD to a label

# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]

# .       create a merge commit using the original merge commit's

# .       message (or the oneline, if no original merge commit was

# .       specified). Use -c <commit> to reword the commit message.

#

# These lines can be re-ordered; they are executed from top to bottom.

#

# If you remove a line here THAT COMMIT WILL BE LOST.

#

#       However, if you remove everything, the rebase will be aborted.

#

#

# Note that empty commits are commented out



>> pick -> fixup 으로 수정하고 코드 편집기의 내용을 저장 후 종료

pick b2e7b0b readme-edit-v4

fixup 71d869f Fix typo


esc 후 :wq!



Successfully rebased and updated refs/heads/readmd-edit-v4.

(b2e7b0b readme-edit-v4 와 71d869f Fix typo 의 두 개의 commit이 하나로 합쳐졌음)



>> master branch 에 통합하기

ihongdon-ui-MacBook-Pro:git-test ihongdon$ git checkout master

Switched to branch 'master'

ihongdon-ui-MacBook-Pro:git-test ihongdon$ git merge --no-ff readmd-edit-v4

Merge made by the 'recursive' strategy.

 READMD.md | 1 +

 1 file changed, 1 insertion(+)

ihongdon-ui-MacBook-Pro:git-test ihongdon$ 

 





  3. 원격 Repository 에 내보내기 (push)


pull, push, pull request 의 작업 흐름은 아래의 도식을 참고하세요. 





  • git remote add : 원격 repository 등록 
     (origin이라는 식별자가 git@github.com:hdlee4u/git-test.git 을 가리킴)


ihongdon-ui-MacBook-Pro:git-test ihongdon$ git remote add origin git@github.com:hdlee4u/git-test.git

 




  • git push : 로컬 repository의 내용을 원격 repository에 전송


ihongdon-ui-MacBook-Pro:git-test ihongdon$ git push -u origin master

Warning: Permanently added the RSA host key for IP address '192.30.255.113' to the list of known hosts.

Enter passphrase for key '/Users/ihongdon/.ssh/id_rsa': 

Enumerating objects: 20, done.

Counting objects: 100% (20/20), done.

Delta compression using up to 8 threads.

Compressing objects: 100% (14/14), done.

Writing objects: 100% (20/20), 1.86 KiB | 1.86 MiB/s, done.

Total 20 (delta 5), reused 0 (delta 0)

remote: Resolving deltas: 100% (5/5), done.

To github.com:hdlee4u/git-test.git

 * [new branch]      master -> master

Branch 'master' set up to track remote branch 'master' from 'origin'.

ihongdon-ui-MacBook-Pro:git-test ihongdon$ 

 




로컬 repository에서 만들었던 내용들이 git push 로 원격 repository에 보내기를 한 결과, GitHub 페이지에 가보면 아래와 같이 'git-test' repository의 master branch 에 README.md 파일이 올라와 있습니다. 

 




>> 로컬 repository 의 master branch 이외의 'readme-edit-v2' branch를 원격 repositiory에 전송하기



ihongdon-ui-MacBook-Pro:git-test ihongdon$ git checkout readme-edit-v2

Switched to branch 'readme-edit-v2'

ihongdon-ui-MacBook-Pro:git-test ihongdon$ git push -u origin readme-edit-v2

Enter passphrase for key '/Users/ihongdon/.ssh/id_rsa': 

Total 0 (delta 0), reused 0 (delta 0)

To github.com:hdlee4u/git-test.git

 * [new branch]      readme-edit-v2 -> readme-edit-v2

Branch 'readme-edit-v2' set up to track remote branch 'readme-edit-v2' from 'origin'.

ihongdon-ui-MacBook-Pro:git-test ihongdon$

 




  4. 원격 repository 에서 가져오기 (clone)


여기서 부터는 같이 협업을 하는 '제 3의 개발자'가 있다고 가정하고, 저의 repository에 저장되어 있는 코드를 '제 3의 개발자'가 자신의 repository로 가져다가 작업을 한다고 가정을 하고 아래 글들을 읽으시길 바랍니다.  폴더를 새로 만들고, 폴더 사이를 왔다갔다 하는게 '제 3의 개발자'의 개발 환경으로 이동하는 것이라고 여기면 되겠습니다. 


>> 새로운 폴더 만들기



ihongdon-ui-MacBook-Pro:git-test ihongdon$ cd

ihongdon-ui-MacBook-Pro:~ ihongdon$ pwd

/Users/ihongdon

ihongdon-ui-MacBook-Pro:~ ihongdon$ cd Documents

ihongdon-ui-MacBook-Pro:Documents ihongdon$ cd GitHub

ihongdon-ui-MacBook-Pro:GitHub ihongdon$ mkdir git-test2

ihongdon-ui-MacBook-Pro:GitHub ihongdon$ cd git-test2

ihongdon-ui-MacBook-Pro:git-test2 ihongdon$ 

 




  • git clone remote_repository : 원격 repository 복사해서 가져오기


ihongdon-ui-MacBook-Pro:git-test2 ihongdon$ git clone git@github.com:hdlee4u/git-test.git

Cloning into 'git-test'...

Enter passphrase for key '/Users/ihongdon/.ssh/id_rsa': xxxxxxxx

remote: Counting objects: 20, done.

remote: Compressing objects: 100% (9/9), done.

Receiving objects: 100% (20/20), done.

Resolving deltas: 100% (5/5), done.

remote: Total 20 (delta 5), reused 20 (delta 5), pack-reused 0

ihongdon-ui-MacBook-Pro:git-test2 ihongdon$ 

ihongdon-ui-MacBook-Pro:git-test2 ihongdon$ cd git-test

ihongdon-ui-MacBook-Pro:git-test ihongdon$ git branch -a  # -a 를 붙이면 로컬 repository와 원격 repository 정보를 함께 출력함

* master

  remotes/origin/HEAD -> origin/master

  remotes/origin/master

  remotes/origin/readme-edit-v2

ihongdon-ui-MacBook-Pro:git-test ihongdon$ 

 




  • git checkout -b branch_name origin/branch_name : 원격 repository의 origin branch 를 가져다가 로컬 repository에 branch 생성


ihongdon-ui-MacBook-Pro:git-test ihongdon$ git checkout -b readme-edit-v2 origin/readme-edit-v2

Branch 'readme-edit-v2' set up to track remote branch 'readme-edit-v2' from 'origin'.

Switched to a new branch 'readme-edit-v2'

ihongdon-ui-MacBook-Pro:git-test ihongdon$

 




>> readme-edit-v2 branch에 변경사항 commit



ihongdon-ui-MacBook-Pro:git-test ihongdon$ vi READMD.md 

ihongdon-ui-MacBook-Pro:git-test ihongdon$ cat READMD.md 

# Git Tutorial


## version 1

## version 2

### date : as of 5th Aug.

### test remote branch


This is a git-test repository. 

I'm writing README.md file as a test. 

ihongdon-ui-MacBook-Pro:git-test ihongdon$ 

ihongdon-ui-MacBook-Pro:git-test ihongdon$ git add READMD.md 

ihongdon-ui-MacBook-Pro:git-test ihongdon$ git commit -m "test remote repository with readme-edit-v2"

[readme-edit-v2 c147dbb] test remote repository with readme-edit-v2

 1 file changed, 2 insertions(+), 1 deletion(-)

ihongdon-ui-MacBook-Pro:git-test ihongdon$ 

 




>> readme-edit-v2 commit 한 변경사항을 원격 repository에 전송하기 (push)



ihongdon-ui-MacBook-Pro:git-test ihongdon$ git push

Enter passphrase for key '/Users/ihongdon/.ssh/id_rsa': xxxxxxxx

Enumerating objects: 5, done.

Counting objects: 100% (5/5), done.

Delta compression using up to 8 threads.

Compressing objects: 100% (2/2), done.

Writing objects: 100% (3/3), 399 bytes | 399.00 KiB/s, done.

Total 3 (delta 0), reused 0 (delta 0)

To github.com:hdlee4u/git-test.git

   8254c2e..c147dbb  readme-edit-v2 -> readme-edit-v2

ihongdon-ui-MacBook-Pro:git-test ihongdon$ 

 




>> 이전 작업 폴더로 돌아가서 방금 전에 수정한 readme-edit-v2 branch 가져오기 (pull)



ihongdon-ui-MacBook-Pro:git-test ihongdon$ cd

ihongdon-ui-MacBook-Pro:~ ihongdon$ cd Documents

ihongdon-ui-MacBook-Pro:Documents ihongdon$ cd GitHub

ihongdon-ui-MacBook-Pro:GitHub ihongdon$ cd git-test

ihongdon-ui-MacBook-Pro:git-test ihongdon$ ls -al

total 8

drwxr-xr-x   4 ihongdon  staff  128  8  5 21:35 .

drwxr-xr-x  10 ihongdon  staff  320  8  5 21:38 ..

drwxr-xr-x  14 ihongdon  staff  448  8  5 21:35 .git

-rw-r--r--   1 ihongdon  staff  127  8  5 21:35 READMD.md

ihongdon-ui-MacBook-Pro:git-test ihongdon$ git pull origin readme-edit-v2

Enter passphrase for key '/Users/ihongdon/.ssh/id_rsa': xxxxxxxx

remote: Counting objects: 3, done.

remote: Compressing objects: 100% (2/2), done.

Unpacking objects: 100% (3/3), done.

remote: Total 3 (delta 0), reused 3 (delta 0), pack-reused 0

From github.com:hdlee4u/git-test

 * branch            readme-edit-v2 -> FETCH_HEAD

   8254c2e..c147dbb  readme-edit-v2 -> origin/readme-edit-v2

Updating 8254c2e..c147dbb

Fast-forward

 READMD.md | 3 ++-

 1 file changed, 2 insertions(+), 1 deletion(-)

ihongdon-ui-MacBook-Pro:git-test ihongdon$ 

ihongdon-ui-MacBook-Pro:git-test ihongdon$ cat READMD.md 

# Git Tutorial


## version 1

## version 2

### date : as of 5th Aug.

### test remote branch


This is a git-test repository. 

I'm writing README.md file as a test.

ihongdon-ui-MacBook-Pro:git-test ihongdon$ 

 



Git, GitHub 을 한번도 사용해보지 않은 분이 이번 포스팅을 보게 되면 '이게 다 무슨 얘기지?' 하고 어리둥절 할 것 같습니다. ^^;;;


아무래도 이번 포스팅을 Git 을 사용하시는 분들 중에서 Git 명령어가 잘 기억이 안날 때 참고할 수 있는 용도로 사용하는게 좋을 것 같습니다. 


많은 도움이 되었기를 바랍니다. 


728x90
반응형
Posted by Rfriend
,


이번 포스팅에서는 GitHub 간단 사용법에 대해서 소개하겠습니다.

 

GitHub은 여러 명의 개발자들이 언제 어디서나 협업을 하면서 코드를 공유하고 버전 관리를 할 수 있게 해주는 분산형 Git Repository 호스팅 서비스 플랫폼입니다.

 

GitGitHub은 다른 것인데요, Stackoverflow[1]에 둘을 비교 설명한 내용이 있어서 소개합니다.

 


Git은 버전 관리 시스템이며소스 코드 이력을 관리하는 툴입니다

(Git is a revision control system, a tool to manage your source code history.)


GitHub은 Git repositories를 위한 호스팅 서비스 입니다

(GitHub is a hosting service for Git repositories.)


따라서 Git과 GitHub은 똑같은 것이 아닙니다

Git 은 툴이며, GitHub은 Git을 사용하는 프로젝트를 위한 서비스입니다. 

(So they are not the same thing: Git is the toolGitHub is the service for projects that use Git.)

 



Git
은 리눅스의 창시자인 Linus Torvalds2005년에 기존의 리눅스 커널 개발에 사용하고 있던 버전 관리 시스템의 라이센스가 변경되면서 새로운 시스템을 찾는 과정에서 Git 
을 만들었다고 합니다. (진정 Linux Torvalds는 오픈소스계의 아버지인가 봅니다!)[2]

 

아이러니 한 것은 오픈소스에 적대적이었던 마이크로소프트가 세계 최대 오픈소스 공유 플랫폼인 GitHub2018 6월에 75억 달러(8조원)에 인수를 했다는 점입니다. 세상 참 오래 살고 볼 일입니다. (MS에 대한 불신 때문일까요? MSGitHub 인수 발표 이후에 GitHub과 같은 Git Repository 호스팅서비스인 GitLab으로 망명하는 개발자들도 있습니다)

 

만약 이 포스팅을 보고 있는 분이 팀으로 협업을 하는 개발자가 아니라면, 개인용 랩탑 컴퓨터로 R이나 Python, SAS, MATLAP 등으로 혼자 분석 업무 만 담당하는 분이라면 GitHub을 왜 써야 하나(Why GitHub?) 궁금증이 생길 것입니다. 아래의 그림은 Vincent Driessen 이라는 개발자께서 ‘A successful Git branching model’[3]이라는 제목으로 Why Git?, Decentralized but centralized, The main branches, Supporting branches 등에 대해서 블로그에 소개한 내용입니다. 시간의 흐름에 따라서 여러 명의 개발자가 협업하면서 코드 버전을 관리하는 과정을 볼 수 있을 텐데요, Git과 같은 버전관리 시스템이 없다면 무척 애를 먹을 것이라고 예상할 수 있습니다


비단 협업 뿐만이 아니더라도, 분석가가 여러 버전의 분석 코드를 작성하다 보면 그저께 코딩했던 데이터 전처리 R코드가 어디있더라?’, ‘어제 분석했던 Random Forest Hyperparameter 설정값을 수정하고 덮어써버렸네뭐였더라?’, ‘000로 부터 그저께 Python 코드를 이메일로 받았었는데 그게 어디있지?’와 같은 종류의 어려움에 처할 수 있는데요, 버전 관리 시스템이 있다면 이를 피할 수 있게됩니다.

 


[ 그림 1. A successful Git branching model (by Vincent Driessen) ]


* Source: https://nvie.com/posts/a-successful-git-branching-model/

 


코드 버전 관리를 도와주는 버전 관리 시스템은 크게 (1) 로컬 버전 관리 시스템 (Local Version Control System), (2) 중앙 집중식 버전 관리 시스템 (Centralized Version Control System), (3) 분산 버전 관리 시스템(Distributed Version Control System)으로 구분할 수 있으며, Git은 이중에서 분산 버전 관리 시스템에 해당합니다.

(* Reference: https://git-scm.com/book/ko/v1)

 

 

[ 그림 2. 버전 관리 시스템 (Version Control System) ]

 


 

중앙 집중식 버전 관리 시스템(Subversion, Perforce )은 사용 방법이 분산형 대비 상대적으로 쉽다는 장점이 있습니다. 하지만 코드가 저장되어 있는 중앙 서버에 장애가 발생했다 거나, 개발자 중에 한명이 코드 커밋을 완료하지 않고 퇴근을 해버린다거나 하면 버전 관리 기능이 마비가 되어 협업을 할 수가 없는 단점이 있습니다.

 

분산 버전 관리 시스템은 중앙 집중식 버전 관리 시스템과 장점과 단점이 정반대입니다. 장점으로는 클라이언트가 저장소 자체를 복제하게 되므로 중앙 서버에 장애가 발생해도 클라이언트에서 개발 작업을 진행하는데 문제가 없으며, 여러 그룹과 협업을 진행하는데도 문제가 없습니다. 반면에, 처음 분산형을 사용하는 분이라면 전체 구조와 흐름을 이해하고 능숙하게 사용하는데 (중앙 집중형 대비 상대적으로) 어렵다는 단점이 있습니다.

(저는 5년 전에 Coursera에서 처음으로 GitHub에 대해 20여분짜리 동영상 강의를 접하였었는데요, 뭐가 여기 저기를 왔다 갔다 하는데요, 강사가 무슨 얘기를 하는지 도통 이해할 수가 없었던 기억이 있습니다. ‘그냥 코드 카피해서 게시판에 페이스트 해서 숙제 제출하면 안되나?’ 라고 투덜거렸었습니다. ^^;)

 

아래의 그림3은 GitHub에서 여러 명의 개발자가 협업을 할 때, 소스 코드를 수정하고 이를 소스 코드에 반영해달라고 요청하는 Pull Request를 하는 절차를 도식화한 것입니다. [2] 클라우드 상의 GitHub에서 타인의 git과 자기의 git 사이의 흐름, 그리고 자신의 로컬 개발환경 사이의 전체 흐름에 대해서 살펴보면 GitHub의 사용 절차를 이해하는데 도움이 될 것이라고 생각합니다.


아래의 그림3 에서는 (1) 다른 사람의 master branch를 자신의 github으로 Fork 해서 (2) 로컬 개발환경으로 pull 하고, (3) topic branch를 만들어서 (4) 수정 작업을 한 후, (5) 자신의 github에 원격 branch 작성을 push하고, (6) original master branch를 가진 사람에게 pull request를 전송해서 피드백을 요청하면, (7) original master branch 주인이 pull request를 열고 차이점을 비교한 후 만족스러우면 merge 하는 절차입니다. 



[ 그림 3. Git Pull Request Workflow ]

 

 

 

최근 Mac 에는 Git이 기본으로 설치되어 있으며, 리눅스나 윈도우즈는 자신이 사용하는 종류에 맞게 다운받아서 설치를 해주어야 합니다. Git 설치는 https://git-scm.com/book/ko/v2/시작하기-Git-설치를 참고하세요. [4]

 

GitHub.com account 생성 및 SSH 인증(https://github.com/join)을 모두 끝마쳤다는 가정 하에 이제부터 GitHub의 간단한 사용을 예를 들어서 소개하겠습니다

 

아래의 예는 GitHub hello world (https://guides.github.com/activities/hello-world/) 튜토리얼을 한글로 번역한 내용입니다. [5]  위의 그림3은 다른 사람의 git을 fork 하는 것으로 시작하는데요, 아래의 예는 좀더 간단하게 다른 사람의 git이 아니라 자기 자신의 github 안의 repository 를 가지고 pull request 해보는 예입니다. pull request 는 Git의 꽃이므로 정확하게 이해하는게 좋겠습니다. 


  • Repository 생성하고 사용하기
  • 새로운 Branch 시작하고 관리하기
  • 파일에 변경사항 만들고 GitHubpush 하기 (commit)
  • Pull request 열고 합치기(merge)

 

[1 단계] Repository 생성


Repository는 보통 하나의 프로젝트를 구성하기 위해 사용합니다. Repository는 여러 개의 폴더, 파일, 이미지, 동영상, 데이터셋을 가질 수 있습니다. Repository에 코드를 저장하고, 다른 개발자와 코드를 공유하며, 의견도 나누고, 코드 수정도 같이 할 수 있습니다.

 

(1)   GitHub.com 의 우측 상단에 ‘+’ 메뉴를 클릭한 후,

(2)   ‘New repository’ 하위 메뉴를 선택하면 아래와 같은 화면이 나타납니다.

(3)   Repository name‘hello-world’라고 이름을 기입해주고,

(4)   ‘Public’ 외부 공개 모드를 선택해주세요. 참고로, Private은 비공개인 대신에 유료 서비스 입니다.

(5)   ‘Initialize this repository with a README’ 를 선택 후 ‘Create repository’ 단추를 눌러주세요.




 

짜잔~! ‘hello-world’ Repository가 생성되었습니다.



 

 

[2 단계] Branch 생성

 

Repository에 다른 버전의 작업을 할 때 새로운 Branch를 만듭니다. Repository를 처음 만들면 디폴트 설정으로 master 라는 이름의 최종적인 Branch가 만들어집니다. Branch에서 작업을 실험도 하고 수정을 한 후에 master에 커밋합니다.

 Master branch에서 새로운 branch를 만들게 되면 그 시점의 master를 그대로 복사합니다. 만약 당신이 당신의 branch에서 작업을 하는 동안 다른 누군가가 master branch에서 수정을 한 경우에 당신은 변경사항을 pull해서 가져올 수 있습니다.

 

아래의 다이어그램은 [5]

Ÿ   Master branch 에서

Ÿ   Feature라는 이름의 새로운 branch를 생성하고,

Ÿ   Pull request 와 변경했으면 하는 사항에 대한 토론을 진행한 후,

Ÿ   Master branch ‘feature branch’를 병합(merge)하는

작업 절차를 보여줍니다.

 

 

 

새로운 branch를 만드는 방법은

(1)   ‘hello-world’ repository로 가서

(2)   ‘branch: master’라는 파일 리스트의 제일 위에 있는 drop down 메뉴를 선택 후

(3)   Branch 텍스트 상자에 ‘readme-edits’이라는 이름의 Branch 이름을 입력하고,

(4)   파란색의 ‘Create branch’ 상자를 선택하거나 키보드의 ‘Enter’를 치면 됩니다.

 

이제 ‘hello-world’ repository 안에 ‘master’ branch 그리고 master branch를 복사한 ‘readme-edits’ branch의 두개 branch가 생겼습니다.

 

 


[3 단계] 수정 후 commit 하기

 

(1)   README.md 파일을 선택 후 우측 상단의 연필 모양 아이콘을 클릭

(2)   편집창에서 수정사항 쓰기

(3)   편집창 아래에 있는 ‘commit message’란에 수정사항에 대한 부연설명 쓰기
(
무엇을, 왜 수정했는가를 써서 다른 개발자가 쉽게 이해할 수 있도록)

(4)   ‘Commit changes’ 단추 클릭

하면 Master에서 복사한 ‘readme-edits’ branch를 수정할 수 있습니다. 이제 애초의 master branch와 방금 수정한 readme-edits branch는 서로 다른 branch가 되었습니다.

 



 

 

[4 단계] Pull Request 열기

 

Pull Request를 통해서 당신이 만든 수정사항을 제안하고 다른 사람이 검토해줄 것을 요청하며 수정사항을 master branch에 반영하도록 할 수 있습니다. Pull Request master branch와 새로 만든 branch 간의 다른 점(differences, diffs)을 녹색이나 빨간색으로 보여줍니다. 


GitHub @mention 시스템을 이용하여 특정 팀이나 사람에게 피드백을 요청할 수도 있습니다.


(1)   Pull Request 탭을 클릭하여 나타난 페이지에서 ‘New pull request’ 단추를 클릭



 

(2)   변경점 비교 창에서 비교를 하려고 하는 ‘readme-edits’ branch를 선택하면 master branch와 차이점을 비교하게 됩니다. 비교 페이지에서 추가(+), 삭제(-), 변경사항을 살펴봅니다.



 

(3)   비교한 변경사항이 원하는 내용임을 확인하였으면 Pull request의 제목과 설명을 추가한 후에 ‘Create pull request’ 단추를 누릅니다.

 


 

 

[5 단계] Pull Request 합치기 (merge)

 

마지막 단계로서, ‘readme-edits’ branch에서 수정한 사항을 원래의 master branch에 합쳐보겠습니다.

 

(1)   Master branch에 변경점을 반영하기 위해 ‘Merge pull request’ 녹색 단추 클릭

(2)   ‘Confirm merge’ 클릭

(3)   변경사항이 master branch에 모두 반영이 되었으므로 ‘Delete branch’ 자주색 단추를 눌러서 ‘readme-edits’ branch 삭제하기


 

드디어 pull requestoriginal master branch에 합치는 것을 끝마쳤습니다. ^^b

‘readme-edits’ branch에서 수정했던 사항들이 original ‘master’ branch에 합쳐진 것을 확인할 수 있습니다.



다음번 포스팅에서는 터미널에서 Git을 사용해서 GitHub Repository에 commit 하는 방법을 소개하겠습니다. 


많은 도움이 되었기를 바랍니다. 

 

* Reference

[1] https://stackoverflow.com/questions/13321556/difference-between-git-and-github

[2] ‘소셜 코딩으로 이끄는 GitHub 실천 기술’, 오오츠카 히로키 지음/윤인성 옮김, Jpub

[3] https://nvie.com/posts/a-successful-git-branching-model/

[4] Git 설치 및 명령어 참고: https://git-scm.com/

[5] GitHub hello world: https://guides.github.com/activities/hello-world/

 

728x90
반응형
Posted by Rfriend
,

이번 포스팅에서는 리눅스 정규 표현식 (Linux Regular Expression)에 대해서 알아보겠습니다. 


정규 표현식은 데이터 검색, 복잡한 패턴 매칭을 도와주는 특별한 문자입니다. 정규표현식(regular expression)은 줄여서 'regexp' 또는 'regex' 라고도 합니다. 


정규 표현식은 리눅스 뿐만 아니라 유닉스, SQL, R, Python 등 에서도 사용할 수 있습니다. 지난번 포스팅에서 소개했던 grep 문과 함께 사용하면 정말로 강력하게 문자열 패턴 매칭, 검색을 할 수가 있습니다. 


정규 표현식(Regular expressions)에 대해서 모르는 상태에서 다른 사람이 짜놓은 정규 표현식을 처음으로 보게 되면 '에잉? 이게 뭐지? 갓난 아기가 컴퓨터 자판를 가지고 마구잡이로 장난하면서 두둘겨 놓은건가?' 이런 생각이 들겁니다.  알면 해독이 되는데요, 모르면 도통 이게 뭐에 쓰는 물건인가, 이게 프로그래밍 언어 맞나 싶게 요상하게 보이거든요. ^^;  암튼, 알아두면 문자열 패턴 매칭, 검색 시 정말 유용합니다. 



정규 표현식에는 3가지 유형이 있습니다. 


  • 기본 정규 표현식 (Basic Regular Expressions)
  • 간격 정규 표현식 (Interval Regular Expressions)
  • 확장 정규 표현식 (Extended Regular Expression)





다음은 예제로 사용할 텍스트 문서입니다. 



[MacBook-Pro:Documents rfriend$ cat mylove.txt 

drum

photography

data science

greenplum

python

R

book

movie

dancing

singing

milk

english

gangnam style

new face

soccer

pingpong

sleeping

martial art

jogging

blogging

apple

grape

banana

tomato

bibimbab

kimchi

@email

123_abc_d4e5

xyz123_abc_d4e5

123_abc_d4e5.xyz

xyz123_abc_d4e5.xyz

 



먼저 기본 정규 표현식 (Basic Regular Expressions)을 예를 들어서 살펴보겠습니다. 

정규표현식은 큰 따옴표(" ")안에 매칭할 문자와 함께 사용합니다.  



1. 문자열의 처음 시작 부분 매칭: ^


참고로 -n 은 행번호를 출력하라는 뜻입니다. 



[MacBook-Pro:Documents rfriend$ grep -n "^m" mylove.txt 

8:movie

11:milk

18:martial art

 




2. 문자열의 끝 부분 매칭$



[MacBook-Pro:Documents rfriend$ grep -n "m$" mylove.txt 

1:drum

4:greenplum

 




3. 점의 개수만큼 아무 문자나 대체: ...



[MacBook-Pro:Documents rfriend$ grep -n "m..." mylove.txt 

8:movie

11:milk

13:gangnam style

18:martial art

24:tomato

25:bibimbab

26:kimchi


[MacBook-Pro:Documents rfriend$ grep -n "m......" mylove.txt 

13:gangnam style

18:martial art


[MacBook-Pro:Documents rfriend$ grep -n "..m..." mylove.txt 

13:gangnam style

24:tomato

25:bibimbab

26:kimchi


[MacBook-Pro:Documents rfriend$ grep -n "....m" mylove.txt 

4:greenplum

13:gangnam style

25:bibimbab

 




4. * 부호 앞의 문자와 여러개 매칭 : *



[MacBook-Pro:Documents rfriend$ grep "app*" mylove.txt 

photography

apple

grape


[MacBook-Pro:Documents rfriend$ grep "^app" mylove.txt 

apple

 




5. 특수 문자와 매칭\



[MacBook-Pro:Documents rfriend$ grep "\@" mylove.txt 

@email

 




6. a나 b로 시작하는 모든 행을 찾아서 출력 : ^[ab]



[MacBook-Pro:Documents rfriend$ grep "^[ab]" mylove.txt 

book

blogging

apple

banana

bibimbab

 




7. 0~9 사이 숫자로 시작하는 단어 :  ^[0-9]



[MacBook-Pro:Documents rfriend$ grep ^[0-9] mylove.txt 

123_abc_d4e5

123_abc_d4e5.xyz

 




8. x~z 사이 알파벳으로 끝나는 단어 : [a-e]$



[MacBook-Pro:Documents rfriend$ grep [x-z]$ mylove.txt 

photography

123_abc_d4e5.xyz

xyz123_abc_d4e5.xyz

 




다음의 예는 간격 정규 표현식(Interval Regular Expressions) 입니다.  

간격 정규 표현식은 문자열 안에서 특정 문자가 몇 번 출현 했는지를 가지고 패턴 매칭할 때 사용합니다. 


9. 앞의 문자와 'n'번 정확하게 매칭: {n}


grep -E "character"\{n} 의 형식으로 사용합니다. 



[MacBook-Pro:Documents rfriend$ grep "g" mylove.txt 

photography

greenplum

dancing

singing

english

gangnam style

pingpong

sleeping

jogging

blogging

grape


[MacBook-Pro:Documents rfriend$ grep -E "g"\{2} mylove.txt 

jogging

blogging

 




마지막으로, 확장 정규 표현식(Extended Regular Expressions) 입니다.  확장 정규 표현식은 한 개 이상의 표현식(combinations of more than one expressions)을 결합하여 사용할 수 있게 해줍니다. 



10. \+ 앞의 문자가 한번 이상 출현한 문자열과 매칭 \+



[MacBook-Pro:Documents rfriend$ grep "k" mylove.txt 

book

milk

kimchi


-- 문자 'k'의 앞에 'o'가 출현한 문자열만 선별하고 싶은 경우 "o\+k" 정규표현식 사용

[MacBook-Pro:Documents rfriend$ grep "o\+k" mylove.txt 

book

 



* Reference : https://www.guru99.com/linux-regular-expressions.html


많은 도움이 되었기를 바랍니다. 

728x90
반응형
Posted by Rfriend
,

이번 포스팅에서는 리눅스의 grep 을 사용하여 하나의 파일이나 디렉토리 안의 여러개의 파일에서 특정 패턴에 매칭되는 행을 찾아서 출력하는 다양한 옵션, 방법을 소개하겠습니다.  특히 정규 표현식(regular expression) 까지 함께 사용하면 매우 강력하게 파일 내 특정 패턴을 찾을 수 있어서 굉장히 유용합니다. 



[ LINUX grep command : 문자열 패턴 검색 후 출력 ]





먼저, 예제로 사용할 수 있도록 demo_file.txt의 텍스트 파일을 준비하였습니다. 



[MacBook-Pro:~ rfriend$ ssh gpadmin@192.168.188.131

gpadmin@192.168.188.131's password: xxxxxxxx

Last login: Sat Dec  9 01:06:33 2017 from 192.168.188.1

[gpadmin@mdw ~]$ ls -al

합계 544860

drwx------  8 gpadmin gpadmin      4096 2017-12-09 01:12 .

drwxr-xr-x. 4 root    root         4096 2017-11-08 20:04 ..

-rw-------  1 gpadmin gpadmin      4792 2017-12-09 01:10 .bash_history

-rw-r--r--  1 gpadmin gpadmin        18 2014-10-16 22:56 .bash_logout

-rw-r--r--  1 gpadmin gpadmin       398 2017-12-04 13:45 .bash_profile

-rw-r--r--  1 gpadmin gpadmin       124 2014-10-16 22:56 .bashrc

-rw-rw-r--  1 gpadmin gpadmin        28 2017-11-08 20:12 .gphostcache

drwxrwxr-x  2 gpadmin gpadmin      4096 2017-12-04 13:43 .oracle_jre_usage

-rw-------  1 gpadmin gpadmin        32 2017-11-08 20:21 .pgpass

-rw-rw-r--  1 gpadmin gpadmin         0 2017-11-08 20:21 .pgpass.1510140115

-rw-------  1 gpadmin gpadmin      2066 2017-12-09 00:21 .psql_history

drwx------  2 gpadmin gpadmin      4096 2017-11-08 20:05 .ssh

drwxrwxr-x  2 gpadmin gpadmin      4096 2017-12-06 20:10 command

-rw-r--r--  1 gpadmin gpadmin       233 2017-12-09 01:12 demo_file.txt

drwxrwxr-x  2 gpadmin gpadmin      4096 2017-12-08 09:45 gpAdminLogs

drwxr-xr-x  2 gpadmin gpadmin      4096 2017-11-08 20:14 gpconfigs

drwxrwxr-x  2 gpadmin gpadmin      4096 2017-12-07 20:29 gptext

-rwxr-xr-x  1 gpadmin gpadmin      2916 2017-12-04 13:42 gptext_install_config

-rwxr-xr-x  1 gpadmin gpadmin 192264305 2017-09-19 09:20 greenplum-text-2.1.3-rhel6_x86_64.bin

-rw-r--r--  1 gpadmin gpadmin 191435368 2017-12-04 12:36 greenplum-text-2.1.3-rhel6_x86_64.tar.gz

-rw-r--r--  1 gpadmin gpadmin 174157387 2017-12-04 13:28 jdk-8u161-linux-x64.rpm


[gpadmin@mdw ~]$ cat demo_file.txt

THIS LINE IS THE 1ST UPPER CASE LINE IN THIS FILE.

this line is the 1st lower case line in this file.

This Line Has All Its First Character Of The Word With Upper Case.


Two lines above this line is empty.

And this is the last line.


[gpadmin@mdw ~]$ 

 



grep 의 기본 syntax 는 다음과 같습니다. 


  grep [OPTIONS] PATTERN [FILE...] 



하나씩 예를 들어가면서 설명하겠습니다. 




1. 하나의 파일에서 한개의 패턴을 검색하여 해당되는 행 출력하기: grep PATTERN [FILE]



[gpadmin@mdw ~]$ grep "line" demo_file.txt

this line is the 1st lower case line in this file.

Two lines above this line is empty.

And this is the last line.

[gpadmin@mdw ~]$ 

 




2. grep 검색 패턴에 맞는 부분은 색깔을 다르게 해서 보기: --color



[gpadmin@mdw ~]$ grep  --color  "line"  demo_file.txt

this line is the 1st lower case line in this file.

Two lines above this line is empty.

And this is the last line.

[gpadmin@mdw ~]$ 

 



grep --color 앞부분에 GREP_COLOR="1;32" 로 패턴과 매칭되는 부분의 색깔을 지정할 수 있습니다. 

  • GREP_COLOR="1;32"  : 초록색 (green)
  • GREP_COLOR=:1;34"  : 보라색 (violet)
  • GREP_COLOR="1;36"  : 하늘색 (light blue)




3. 대소문자 구분없이(case in-sensitive) 패턴 검색하여 행 출력: -i


2번에서는 검색이 안되었던 대문자 "LINE"도 이번에는 검색이 되었습니다. 



[gpadmin@mdw ~]$ grep  --color  -i  "line"  demo_file.txt

THIS LINE IS THE 1ST UPPER CASE LINE IN THIS FILE.

this line is the 1st lower case line in this file.

This Line Has All Its First Character Of The Word With Upper Case.

Two lines above this line is empty.

And this is the last line.

[gpadmin@mdw ~]$ 

 




4. 파일 이름에 와이드카드 *(Asterisk)를 사용하여 다수의 파일에서 패턴 검색하여 행 출력: filename*.txt


먼저 cp를 사용하여 demo_file.txt 파일을 demo_file2.txt 라는 파일 이름으로 복사를 해서 2개의 파일을 만들었습니다. 



[gpadmin@mdw ~]$ cp  demo_file.txt  demo_file2.txt




다음으로 파일 이름의 중간에 와이드카드 '*(Asterisk)'를 사용하여 파일 이름 demo_*.txt 에서 * 부분에 무엇이 있든지 간에 이에 해당하는 다수의 파일을 찾아서 패턴 검색 후 출력을 하게 됩니다. 3번에서와는 달리 이번에는 출력이 될 때 파일 이름(demo_file.txt, demo_file2.txt)이 행의 출력 맨 앞 부분에 나타납니다. 



[gpadmin@mdw ~]$ grep --color -i "line" demo_*.txt

demo_file.txt:THIS LINE IS THE 1ST UPPER CASE LINE IN THIS FILE.

demo_file.txt:this line is the 1st lower case line in this file.

demo_file.txt:This Line Has All Its First Character Of The Word With Upper Case.

demo_file.txt:Two lines above this line is empty.

demo_file.txt:And this is the last line.

demo_file2.txt:THIS LINE IS THE 1ST UPPER CASE LINE IN THIS FILE.

demo_file2.txt:this line is the 1st lower case line in this file.

demo_file2.txt:This Line Has All Its First Character Of The Word With Upper Case.

demo_file2.txt:Two lines above this line is empty.

demo_file2.txt:And this is the last line.





5. 서브 디렉토리까지 반복적으로 패턴 검색하여 행 출력: * (Asterisk only, without filename)



[gpadmin@mdw ~]$ grep  --color -i  "line"  *

demo_file.txt:THIS LINE IS THE 1ST UPPER CASE LINE IN THIS FILE.

demo_file.txt:this line is the 1st lower case line in this file.

demo_file.txt:This Line Has All Its First Character Of The Word With Upper Case.

demo_file.txt:Two lines above this line is empty.

demo_file.txt:And this is the last line.

demo_file2.txt:THIS LINE IS THE 1ST UPPER CASE LINE IN THIS FILE.

demo_file2.txt:this line is the 1st lower case line in this file.

demo_file2.txt:This Line Has All Its First Character Of The Word With Upper Case.

demo_file2.txt:Two lines above this line is empty.

demo_file2.txt:And this is the last line.

greenplum-text-2.1.3-rhel6_x86_64.bin:support, invoicing, and online services. Licensee is responsible for obtaining

greenplum-text-2.1.3-rhel6_x86_64.bin:    if tablog.getNumLines() > 1:

greenplum-text-2.1.3-rhel6_x86_64.bin:        for line in open(to_append_file).readlines():

greenplum-text-2.1.3-rhel6_x86_64.bin:            line = line.strip()

greenplum-text-2.1.3-rhel6_x86_64.bin:            if line.startswith('#') or line == '':

greenplum-text-2.1.3-rhel6_x86_64.bin:            if len(line.split()) != 1:

greenplum-text-2.1.3-rhel6_x86_64.bin:        for line in open(to_append_file).readlines():

greenplum-text-2.1.3-rhel6_x86_64.bin:            line = line.strip()

greenplum-text-2.1.3-rhel6_x86_64.bin:            if line.startswith('#') or line == '':

greenplum-text-2.1.3-rhel6_x86_64.bin:            if line.find('=>') == -1:

greenplum-text-2.1.3-rhel6_x86_64.bin:            parts = line.split('=>')

greenplum-text-2.1.3-rhel6_x86_64.bin:        for line in open(to_append_file).readlines():

greenplum-text-2.1.3-rhel6_x86_64.bin:            line = line.strip()

greenplum-text-2.1.3-rhel6_x86_64.bin:            if line.startswith('#') or line == '':

greenplum-text-2.1.3-rhel6_x86_64.bin:            if line.find('=>') != -1:

greenplum-text-2.1.3-rhel6_x86_64.bin:                parts = line.split('=>')

greenplum-text-2.1.3-rhel6_x86_64.bin:            sys.stdin.readline()

-- 중간 생략 --

Binary file greenplum-text-2.1.3-rhel6_x86_64.tar.gz matches

Binary file jdk-8u161-linux-x64.rpm matches





6. 검색 조건을 뒤집어서(invert), 매칭되지 않는 행을 검색하여 출력: -v



[gpadmin@mdw ~]$ cat demo_file.txt

THIS LINE IS THE 1ST UPPER CASE LINE IN THIS FILE.

this line is the 1st lower case line in this file.

This Line Has All Its First Character Of The Word With Upper Case.


Two lines above this line is empty.

And this is the last line.

[gpadmin@mdw ~]$ 

[gpadmin@mdw ~]$ 

[gpadmin@mdw ~]$ grep  -i  -v  "case"  demo_file.txt


Two lines above this line is empty.

And this is the last line.





7. 매칭되는 행의 번호 같이 보기: -n



[gpadmin@mdw ~]$ grep  --color  --n  "case"  demo_file.txt

1:THIS LINE IS THE 1ST UPPER CASE LINE IN THIS FILE.

2:this line is the 1st lower case line in this file.

3:This Line Has All Its First Character Of The Word With Upper Case.





8. 전체 행이 정확히 일치하는 행만 검색하여 출력: -x



[gpadmin@mdw ~]$ grep  -n  -x  "this line is the 1st lower case line in this file."  demo_file.txt

2:this line is the 1st lower case line in this file.





9. 각 인풋 파일의 매칭되는 행의 개수 출력: -c, --count



[gpadmin@mdw ~]$ grep  -c  "line"  demo_file.txt

3

[gpadmin@mdw ~]$ grep  --count  "line"  demo_file.txt

3





10. 패턴 매칭된 행의 전(Before), 후(After), 중간(Center)의 전/후 행 NUM 개수 만큼 같이 출력하기  : -B NUM, -A NUM, -C NUM



--   10-1. 패턴 매칭된 행의 이전(Before) 행도 NUM 개수 만큼 출력: -B NUM



[gpadmin@mdw ~]$ cat  demo_file.txt

THIS LINE IS THE 1ST UPPER CASE LINE IN THIS FILE.

this line is the 1st lower case line in this file.

This Line Has All Its First Character Of The Word With Upper Case.


Two lines above this line is empty.

And this is the last line.


[gpadmin@mdw ~]$ 

[gpadmin@mdw ~]$ grep  --color -n  -B 2 "First"  demo_file.txt

1-THIS LINE IS THE 1ST UPPER CASE LINE IN THIS FILE.

2-this line is the 1st lower case line in this file.

3:This Line Has All Its First Character Of The Word With Upper Case.

[gpadmin@mdw ~]$ 

 



--   10-2. 패턴 매칭된 행의 이후(After) 행도 NUM 개수 만큼 출력: -A NUM



[gpadmin@mdw ~]$ cat demo_file.txt

THIS LINE IS THE 1ST UPPER CASE LINE IN THIS FILE.

this line is the 1st lower case line in this file.

This Line Has All Its First Character Of The Word With Upper Case.


Two lines above this line is empty.

And this is the last line.


[gpadmin@mdw ~]$ 

[gpadmin@mdw ~]$ grep  --color  -n  -A 2  "First"  demo_file.txt

3:This Line Has All Its First Character Of The Word With Upper Case.

4-

5-Two lines above this line is empty.

[gpadmin@mdw ~]$ 

 



--   10-3. 패턴 매칭된 행을 가운데(Center)에 두고 앞 뒤 행도 NUM 개수 만큼 출력: -C NUM



[gpadmin@mdw ~]$ cat demo_file.txt

THIS LINE IS THE 1ST UPPER CASE LINE IN THIS FILE.

this line is the 1st lower case line in this file.

This Line Has All Its First Character Of The Word With Upper Case.


Two lines above this line is empty.

And this is the last line.


[gpadmin@mdw ~]$ 

[gpadmin@mdw ~]$ grep --color -n  -C 2 "First" demo_file.txt

1-THIS LINE IS THE 1ST UPPER CASE LINE IN THIS FILE.

2-this line is the 1st lower case line in this file.

3:This Line Has All Its First Character Of The Word With Upper Case.

4-

5-Two lines above this line is empty.

[gpadmin@mdw ~]$ 

 




11. 매칭되는 행의 개수가 NUM 을 넘으면 파일 읽기 중단: -m NUM



[gpadmin@mdw ~]$ grep  --color  -n  -i  -m 2  "line"  demo_file.txt

1:THIS LINE IS THE 1ST UPPER CASE LINE IN THIS FILE.

2:this line is the 1st lower case line in this file.

[gpadmin@mdw ~]$ 

 




12. 매칭되는 행 중에서 오직 일치하는(Only matching) 부분만 출력: -o, --only-matching



[gpadmin@mdw ~]$ grep  -n  -o  "First"  demo_file.txt

3:First

[gpadmin@mdw ~]$ grep  -n  --only-matching  "First"  demo_file.txt

3:First

 




13. 행 안에서 패턴과 매칭되는 위치(position)를 출력: -b



[gpadmin@mdw ~]$ grep  -o  -b "First" demo_file.txt

124:First

 




14. 패턴과 매칭되는 파일 이름 출력: -l



[gpadmin@mdw ~]$ grep  -l  "First"  demo_*

demo_file.txt

demo_file2.txt

 




15. grep 옵션 요약 출력 후 exit: --help


오늘 포스팅 내용 중에서 제일 중요한(?), 다른 건 다 까먹어도 이것 하나만 기억하고 있으면 든든한 옵션이 되겠습니다. 

도와주세요 help~!  ^^



[gpadmin@mdw ~]$ grep --help

사용법: grep [옵션]... 패턴 [파일]...

Search for PATTERN in each FILE or standard input.

PATTERN is, by default, a basic regular expression (BRE).

Example: grep -i 'hello world' menu.h main.c


Regexp selection and interpretation:

  -E, --extended-regexp     PATTERN is an extended regular expression (ERE)

  -F, --fixed-strings       PATTERN is a set of newline-separated fixed strings

  -G, --basic-regexp        PATTERN is a basic regular expression (BRE)

  -P, --perl-regexp         PATTERN is a Perl regular expression

  -e, --regexp=PATTERN      use PATTERN for matching

  -f, --file=FILE           obtain PATTERN from FILE

  -i, --ignore-case         ignore case distinctions

  -w, --word-regexp         force PATTERN to match only whole words

  -x, --line-regexp         force PATTERN to match only whole lines

  -z, --null-data           a data line ends in 0 byte, not newline


Miscellaneous:

  -s, --no-messages         suppress error messages

  -v, --invert-match        select non-matching lines

  -V, --version             print version information and exit

      --help                display this help and exit

      --mmap                ignored for backwards compatibility


Output control:

  -m, --max-count=NUM       stop after NUM matches

  -b, --byte-offset         print the byte offset with output lines

  -n, --line-number         print line number with output lines

      --line-buffered       flush output on every line

  -H, --with-filename       print the filename for each match

  -h, --no-filename         suppress the prefixing filename on output

      --label=LABEL         print LABEL as filename for standard input

  -o, --only-matching       show only the part of a line matching PATTERN

  -q, --quiet, --silent     suppress all normal output

      --binary-files=TYPE   assume that binary files are TYPE;

                            TYPE is `binary', `text', or `without-match'

  -a, --text                equivalent to --binary-files=text

  -I                        equivalent to --binary-files=without-match

  -d, --directories=ACTION  how to handle directories;

                            ACTION is `read', `recurse', or `skip'

  -D, --devices=ACTION      how to handle devices, FIFOs and sockets;

                            ACTION is `read' or `skip'

  -R, -r, --recursive       equivalent to --directories=recurse

      --include=FILE_PATTERN  search only files that match FILE_PATTERN

      --exclude=FILE_PATTERN  skip files and directories matching FILE_PATTERN

      --exclude-from=FILE   skip files matching any file pattern from FILE

      --exclude-dir=PATTERN  directories that match PATTERN will be skipped.

  -L, --files-without-match  print only names of FILEs containing no match

  -l, --files-with-matches  print only names of FILEs containing matches

  -c, --count               print only a count of matching lines per FILE

  -T, --initial-tab         make tabs line up (if needed)

  -Z, --null                print 0 byte after FILE name


Context control:

  -B, --before-context=NUM  print NUM lines of leading context

  -A, --after-context=NUM   print NUM lines of trailing context

  -C, --context=NUM         print NUM lines of output context

  -NUM                      same as --context=NUM

      --color[=WHEN],

      --colour[=WHEN]       use markers to highlight the matching strings;

                            WHEN is `always', `never', or `auto'

  -U, --binary              do not strip CR characters at EOL (MSDOS)

  -u, --unix-byte-offsets   report offsets as if CRs were not there (MSDOS)


`egrep' means `grep -E'.  `fgrep' means `grep -F'.

Direct invocation as either `egrep' or `fgrep' is deprecated.

With no FILE, or when FILE is -, read standard input.  If less than two FILEs

are given, assume -h.  Exit status is 0 if any line was selected, 1 otherwise;

if any error occurs and -q was not given, the exit status is 2.


Report bugs to: bug-grep@gnu.org

GNU Grep home page: <http://www.gnu.org/software/grep/>

General help using GNU software: <http://www.gnu.org/gethelp/>

[gpadmin@mdw ~]$ 

 



다음번 포스팅에서는 정규 표현식(regular expression)에 대해서 알아보겠습니다. 


많은 도움이 되었기를 바랍니다. 


* Reference: https://www.computerhope.com/unix/ugrep.htm








728x90
반응형
Posted by Rfriend
,