1 sed

유닉스 시스템 관리자하는 텍스트 파일을 편집하는데 거의 대부분의 시간을 보낸다. 보통 vi나 emacs, jed 같은 전문 텍스트 에디터를 이용해서 이런 일을 한다. 이런 (유저와 상호작용하는)전문 에디터는 훌륭하긴 하지만 한계역시 가지고 있다. 상호작용성이 강점이지만 약점이 될때도 있기 때문이다. 매우 큰(혹은 매우 많은 파일)에 특정 문자열을 다른 문자열로 모두 치환해야 하는 경우를 생각해보자. 전문 에디터를 사용할 경우 엄청나게 많은 시간이 걸릴 것이다.

작업해야 할 문서가 매우 많고, 시간 역시 충분히 많다면 C나 C++로 프로그램을 만들 수도 있을 것이다.

작업해야 할 문서가 매우 많고, 굳이 많은 시간을 쓰고 싶지 않다면, sed를 이용해서 짧은 시간에 이런 일들을 할 수 있다.

sed는 가벼운 stream 에디터로 거의 모든 리눅스(유닉스) 시스템에 설치돼있다. sed의 장점은 다음과 같다.
  1. 아주 가볍기 때문에 스크립트 언어와 궁합이 잘 맞는다.
  2. stream 에디터이기 때문에 파이프와 같은 표준입력을 통해서 데이터를 받아서 처리할 수 있다. 쉘 스크립트는 파이프를 통해서 데이터를 처리하는데, 과 함께 사용하면 파일을 처리하는 강력한 프로그램을 만들 수 있다. 

1.1 GNU Sed

모든 리눅스 운영체제는 GNU Sed를 가지고 있다. 2012년 Ubuntu 12.04를 기준으로 Sed 최신버전은 4.2.1이다.

1.2 Sed 예제

Sed는 편집 명령을 이용해서 입력 데이터를 처리한다. 또한 line-base로 작동한다. 그래서 각 줄 단위로 편집명령이 적용된다. 편집 명령이 적용된 결과는 표준출력된다. (입력 파일을 직접 수정하지는 않는다.)

아래는 간단한 sed 사용 예다.
# sed -e 'd' /etc/services 
이 명령을 실행하면 화면에 아무것도 출력하지 않을 것이다. 왜 그런지 살펴보자. 우리는 sed를 "d" 명령으로 실행했다. sed는 /etc/services 파일을 열어서 모든 줄에 대해서 "d" 명령을 수행한다. "d"는 "delete line"명령을 수행한다. 줄을 지우라는 의미다. 모든 줄에 대해서 "delete line"이 적용되므로 결국 빈 줄을 표준출력한다.

혹시라도 /etc/services의 내용이 모두 사라지진 않았을지 걱정할 필요는 없다. sed는 편집한 결과를 표준출력 할 뿐, 파일의 내용을 수정하지는 않는다. 파일의 내용을 수정하길 원한다면, 표준출력을 임시파일로 저장해서 원본파일을 덮어써야 한다.

다음 명령을 실행해보자
# sed -e '1d' /etc/services | more
이 명령을 실행하면 /etc/service의 첫 라인만 삭제 된다. 앞에 1은 명령이 적용될 범위를 의미하는데, 첫번재 줄을 의미한다. 따라서 "d"명령은 첫째 줄에만 적용이 되어서, 첫 줄만 삭제되는 거다.

1.3 Address ranges

첫째 줄부터 10번째 줄까지 명령 범위를 지정해 보자.
# sed -e '1,10d' /etc/services
"d"명령은 첫번째 줄에서 10번째 줄까지만 적용되고 나머지 줄은 무시한다.

1.4 Regular expressions

이번에는 좀 더 복잡한 예제다. 당신은 /etc/services 파일의 내용을 살펴보길 원한다. 그런데, 주석이 너무 많아서 읽을 맛이 나지 않아서 주석줄은 제외하고 살펴보길 원한다. /etc/service 파일에서 주석은 "#"로 시작이 되므로 줄의 시작 문자가 "#"이면, 삭제하면 될테다.
# sed -e '/^#/d' /etc/services | more
이 코드를 실행하면 주석을 제외한 내용을 보여주는 걸 확인할 수 있다. 어떻게 이런일이 가능한지 분석해보자. 이 코드는 "/^#/"와 "d" 두 부분으로 이루어져있다. d는 삭제하라는 명령이고, 그렇다면 문제는 "/^#/"이 부분의 해석이다. sed는 "//"를 만나면 정규표현식으로 간주해서 해석을 한다. "^#"이 정규표현식인데, ^는 줄의 처음을 의미한다. 즉 이 정규표현은 줄의 "처음에 #이 등장하는 것을 패턴일치 시킨다." 결국 줄의 처음에 #이 등장하면(/^#/) + 삭제(d) 삭제하라는 명령을 수행한다.

정규표현은 아주 강력한 문자열 처리 도구다. 그런만큼 배워야할 내용도 많다. 여기에서는 정규표현에서 자주 사용하는 유용한 몇가지 패턴만 살펴볼 것이다. 자세한 내용은 정규표현의 문서들을 참고한다.

Character설명
^줄의 처음에 일치
$줄의 마지막에 일치
.모든 (단일)문자와 일치
*하나 혹은 그 이상의 앞에 나오는 문자와 일치
![]![]안의 모든 문자와 일치

실제 사용예다.
/./줄에 어떤 문자와도 일치
/../적어도 두개의 문자를 가진 줄과 일치
/^#/#로 시작하는 줄
/^$/공백 줄
/} *$/}로 끝나고 공백 문자가 있는 줄
/abc/'a', 'b', 'c'중 하나라도 포함하는 줄

1.5 범위 지정의 다른 예

기본적으로 sed는 줄단위로 명령을 수행한다. 아래와 같은 코드가 있다고 가정해 보자.
#include <stdio.h>

int main()
{
    printf("Hello world");
}

void hello()
{
}
지금까지의 방법으로는 main 함수만 추려낼 수는 없다. 패턴 상으로 보면 "main("에서 부터 첫줄이 "}"끝났을 때까지를 main 함수로 정의할 수 있지만, 줄단위로만 패턴을 일치하기 때문이다.

이 경우 다음과 같이 main 함수만 가져올 수 있다.
# sed -n -e '/main/,/^}/p' main.c 
int main()
{
    printf("Hello world");
}

사용법은 다음과 같다.
# sed -n -e '/BEGIN/, /END/p' file
이렇게 하면 "BEGIN"패턴과 END 패턴 사이의 모든 줄을 블럭으로 처리한다.

1.6 기본 문자열 치환

치환은 s(substitution)명령을 이용한다. 정규표현 vi에 익숙하다면 이해하기 쉬울 것이다.

모든 5678을 xxxx로 치환
# sed -e s/5678/xxxx/g test.txt 
1234 xxxx hello world 1234xxxx xxxx

파일의 내용을 치환하기 위해서는 표준출력을 임시파일로 저장한 다음 복사하는 스크립트를 만들어야 한다.
sed -e s/5678/xxxx/g test.txt > test.txt.tmp
mv test.txt.tmp test.txt

s를 이용하면 파일의 모든 줄을 검사해서 치환한다. 치환할 구간을 줄 단위로 지정할 수 있다. 첫번째 줄에서 10번째 줄까지만 치환을 적용하려면
# sed -e '1,10s/1234/xxxx/g' test.txt 

공백라인 다음 줄의 처음에 등장하는 bus 문자열을 texi로 변경한다.
# sed -e '/^$/,/^END/s/bus/texi/g' test.txt 

/usr/local을 /usr로 바꾼다.
# sed -e 's/\/usr\/local/\/usr/g' test.txt 

'\'를 포함한 문자열을 치환하려면 역슬래쉬를 사용해야 하는데, 코드가 지저분해 진다. 이럴 땐 ":"을 이용하자.
# sed -e 's:/usr/local:/usr:g' test.txt 

아래와 같은 HTML 문서가 있다.
<b>This</b> is what <b>I</b> meant.

HTML 태그를 없애기 위해서 다음과 같이 sed 코드를 만들었다.
# sed -e 's/<.*>//g' test.txt

우리가 원하는 결과는 "This is what meant."이지만, 실제 결과는 " meant."다. 위의 정규식 대로라면 처음 등장하는 <과 마지막 등장하는 >사이의 모든 문자를 치환해 버리기 때문이다. 다음과 같이 표현식을 바꿔서 원하는 결과를 얻을 수 있다.
$ sed -e 's/<[^>]*>//g' test.txt
[^>]에서 ^는 none의 의미다. 해석하면 "<이 등장한 다음에 처음 등장하는 >" 사이의 문자와 일치한다 라는 의미가 된다.

1.7 복잡한 치환

![ ]는 정규표현식에서 패턴에 추가적인 옵션을 적용하기 위해서 사용한다. 예컨데 '-'로 범위를 지정할 수 있다. 아래는 a에서 부터 x까지 일치하는 단어가 있을 경우 패턴일치한다.
'[a-x]*'

[:alnum:][a-z A-Z 0-9], 모든 알파벳 문자와 숫자
[:alpha:][a-z A-Z], 모든 알파벳 문자
[:blank:]스페이스 문자와 탭문자
[:cntrl:]모든 컨트롤 문자들
[:digit:]숫자, [0-9]
[:graph:]모든 visible 문자들
[:lower:]알파벳 소문자, [a-z]
[:print:]Non-control 문자
[:space:]공백문자
[:upper:]알파벳 대문자, [A-Z]
[:xdigit:]16진수 문자[0-9 a-f A-F]

1.8 매칭된 패턴 사용하기

&를 이용하면 패턴 매칭된 문자열을 저장하고 불러올 수 있다.

echo "yundream 33" | sed -e 's/[a-z]*/My name is &. Age is/'
My name is yundream. Age is 33

1.9 매칭된 패턴 여러 개를 사용하기

()를 이용하면 일치한 패턴을 버퍼에 저장할 수 있다. 이 패턴은 순서대로 \1, \2, ... 으로 불러올 수 있다.
# echo "yundream programmer" | sed -e 's/\([a-z]*\) \([a-z]*\)/My name is \1. Job is \2. Hello \1/'
My name is yundream. Job is programmer. Hello yundream

2 다른 예제들

모든 파일에 포함된 문자열 "xxx"를 "yyy"로 치환
#!/bin/bash

for file in ls *
do
    if [ -f $file ]
    then
        tmpfile="$file.tmp"
        sed -e 's/xxx/yyy/g' $file > $tmpfile
    fi
done


출처 : http://blog.naver.com/fineformula/60179909237


1. find

 

파일 또는 디렉토리 검색

예) 현재경로에서 httpd.conf 파일 찾기, 하위경로 포함

 

 # find ./ -name httpd.conf

 

 

 

예) 최근수정일 15일이 지나고 /home/backup 바로 아래있는 디렉토리 삭제하는 명령

 

 # find /home/backup/ -maxdepth 1 -type d -mtime +15 -exec /bin/rm -rf {} \;

 

 

 

 

2. grep

 

원하는 패턴과 일치하는 줄 출력

예) 80번 포트가 물려 있는 세션 모두 출력

 

 # netstat -ant | grep :80

 

 

 

grep 옵션 중 자주 쓰는 옵션

 

   v  :  패턴 제외한 부분을 출력 (역으로 출력)
   i  :  대소문자 무시
   r  :  하위디렉토리 포함

 

 

 

3. egrep

 

grep 과 같은 역할, 원하는 패턴이 두개 이상일 때 사용

예) 80번 포트가 물려 있는 세션 중 LISTEN 과 TIME_WAIT 가 있는 줄은 제외하고 출력

 

 # netstat -ant | grep :80 | egrep -v "LISTEN|TIME_WAIT"

 

 

 

 

4. awk

 

특정 패턴 기준 n 번째 내용 출력, 옵션 안쓰면 공백을 경계로 사용

예) 위의 결과에서 왼쪽에서 5번째 내용만 출력, 빈칸을 경계로..

 

 # netstat -ant | grep :80 | egrep -v "LISTEN|TIME_WAIT" | awk '{print $5}'

 

 

 

 

5. cut

 

awk 와 유사한 역할, 경계의 기준 문자를 설정하고 n 번째 내용 출력

예) 위의 결과에서 : 문자를 경계로 첫번째 내용 출력

 

 # netstat -ant | grep :80 | egrep -v "LISTEN|TIME_WAIT" | awk '{print $5}' | cut -d : -f 1

 

 

 

 

6. sed

 

특정 패턴을 바꾸거나, 맨 앞이나 맨 뒤에 원하는 패턴 추가, ^ 은 맨 앞을 뜻하고 $ 는 맨 뒤를 뜻한다.

예) 위의 결과물에서 맨 앞에 IP : 패턴을 추가

 

 # netstat -ant | grep :80 | egrep -v "LISTEN|TIME_WAIT" | awk '{print $5}' | cut -d : -f 1 | sed 's/^/IP : /g'

 

 

 

 

7. sort, uniq

 

정렬과 중복 제거, 패턴 검색과 같이 쓰면 효과적

예) 위의 결과물에서 순서대로 정렬하고 중복되면 제거

 

 # netstat -ant | grep :80 | egrep -v "LISTEN|TIME_WAIT" | awk '{print $5}' | cut -d : -f 1 | sed 's/^/IP : /g' | sort | uniq

 

 

 

 

8. wc -l

 

출력된 내용의 라인 수를 출력

예) 위 결과물의 라인 수 구하기

 

 # netstat -ant | grep :80 | egrep -v "LISTEN|TIME_WAIT" | awk '{print $5}' | cut -d : -f 1 | sed 's/^/IP : /g' | sort | uniq | wc -l

 

 

 

 

위에서 산출한 결과물은 현재 웹서버에 접속한 클라이언트 IP 수치다.

TIME_WAIT 세션까지 접속자에 포함 시키고 싶다면 해당 부분을 수정해주면 된다.

이처럼 패턴 검색 명령들을 잘 활용하면 다양한 결과들을 산출 할 수 있다.



합계 구하기

[oracle@mlcp02 tmp]$ ls -al 0805*

-rw-r--r-- 1 oracle oracle 1708 2015-08-05 12:07 0805_01

-rw-r--r-- 1 oracle oracle 5907 2015-08-05 15:53 0805_02

-rw-r--r-- 1 oracle oracle 5523 2015-08-05 16:09 0805_03

-rw-r--r-- 1 oracle oracle  238 2015-08-05 15:48 0805_04


[oracle@mlcp02 tmp]$ ls -al 0805* | awk '{sum += $5} END {print sum}'

13376



'LinuX' 카테고리의 다른 글

linux 프로세스 별 cpu 사용률  (0) 2016.05.10
sed 사용법  (0) 2015.08.24
[Linux] sar 명령어를 통한 시스템 모니터링  (0) 2015.02.12
split 명령어  (0) 2014.10.13
고급 Linux 커맨드 마스터 가이드, 제 2 부  (0) 2009.06.23

Flashback이란?

사용자 실수(논리적 장래)에 의한 손상된 데이터를 Database의 크기와 상관없이 복구를 할수 있는기능이다


△ 9i : Flashback query 

△ 10g : Flashback Database 

          Flashback Drop 

          Flashback Version Query 

          Flashback Transaction Query 

          Flashback Table

△ 11g : Flashback Data Archive


※Oracle Flashback Feature는 10g Standard Edition에서는 지원하지 않는다. 



Flashback Technologies

 Flashback Operation

 Implementation

 Flashback Database

 Flashback logs + Redo logs

 Flashback Drop

 Recycle bin

 Flashback Version Query

 Undo

 Flashback Transaction Query

 Undo

 Flashback Table

 Undo

 Flashback Data Archive

 Flashback archive



Flashback Database를 수행하기 위한 3가지 구성요소 

1. Archive Mode 

Flashback Database 기능을 적용하기 위해서는 Archive Mode로 설정하여야 한다. 

2. Flashback Log File 

Flashback Log File은 오라클 Database를 구성하는 Block(변경되기 이전의 이미지 Block)을 저장하는 로그 파일로서 10g에서 새롭게 소개되고 있는 데이터베이스 복구영역(database recovery area)에 생성되어진다. 

기존의 redo log와의 차이점 

- redo log의 경우에는 archive할 수 있는 기능이 함께 제공되었지만, Flashback Log는 archive 기능이 따로 제공될 필요가 없다.(db_recovery_file_dest, db_recovery_file_dest_size) 

- Flashback Log의 경우에는 물리적인 database 복구에는 사용될수 없다는 점이다. 

3. RVWR 

Background Process Flashback Database 기능이 활성화 되어지면, rvwr이라는 background process가 시작된다.


자세한 내용은 첨부된 파일 참조


006_Flashback data archive_유현재.pdf



Flashback Version Query 이용시 사용하는 가상칼럼

○ versions_startscn : 트랜잭션이 COMMIT 시 SCN즉, 해당 데이터의 버전이 시작될 때 SCN 값

 versions_endscn : 해당 버젼의 유효성이 상실된 SCN

 versions_starttime : 트랜잭션이 COMMIT 시 datetime

 versions_endtime : 해당 버젼이 유효한 최종 datetime

 versions_XID : 해당 데이터의 버전을 생성한트랜잭션-ID

 versions_operation : 해당 트랜잭션의 DML 작업 종류

(U: update, D: delete, I: insert)



Flashback Data Archive

오라클 11g 부터는 마치 Online Redo log 를 Archive 하듯이 Undo Segment 에 있는 commit 된 내용을 특정 테이블 스페이스에 Archive 하여 영구적으로 저장하는 기능을 제공하는데 이것을 Flashback Data Archive(FBDA) 라고 한다. 

FBDA -> undo segment의 내용을 비정기적으로 특정 테이블 스페이스에 저장하는 백그라운드 프로세스



Flashback Data Archive 특징

1. FBDA가 undo segment를 모두 기록하기 전에는 해당 undo segment 재활용되지 않음

2. 최대 10개까지의 FBDA 백그라운드 프로세스 동시에 작업 - 대량의 DML 시 병목현상 방지

3. FBDA 프로세스는 sleep 하고 있다가 특정 시간이 되면 자동으로 활성화 되어 undo segment의 내용을 저장함

   undo의 양이 많을 경우 자주 내려쓰게 되며 기본값은 5분.

4. 해당 데이터는 자동 파티셔닝 되어 저장. 관리자라도 그 내용을 변경할수 없다.

5. Retention time 을 설정하여 데이터를 관리. Retention time 이 지난 데이터는 자동으로 삭제

6. Inset 되는 데이터는 이 기능 사용 안함



<지원하는 DDL>

- Adds | drops | renames | modifies a Column

- Adds | drops | renames a Constraint

- Drop | Truncates a Partition or Sub partition

- TRUNCATE TABLE

- RENAME TABLE

- PARTITION OR SUB PARTITION


<지원하지 않는 DDL>

- 파티션이나 서브파티션을 변경하는 ALTER TABLE 구문

- DROP TABLE


11g R1 과 11g R2에서 지원되는 DDL 차이

 

 11g R1

11g R2 

Truncate 

Alter table

Drop






'OraclE' 카테고리의 다른 글

Auditing Enhancements (aud$ 테이블 관리)  (0) 2016.04.11
dbms_scheduler 변경  (2) 2016.01.04
append 힌트 재대로 사용하시나요?  (0) 2015.03.30
object 변경시 dependency  (0) 2015.01.06
pid로 port 찾기 (lsof)  (0) 2014.09.17

흔히 대량 데이터를 insert 할 때 많은 DBA들이 append 힌트를 사용 하라고 한다.

근데 무작정 append 힌트 쓴다고 과연 빨라질까?


append 힌트는 데이터베이스가 noarchive mode 혹은 table을 nologging 으로 설정 시에만 사용 가능하다.


다음과 같은 상황에서 빠르게 insert 가 가능하다.

1. 대량의 redo를 발생시켜 archive mode에서 log switch를 방해. -> nologging 설정

2. append 힌트 사용시 direct load를 지원하여 버퍼캐쉬를 거치지 않아 rollback 정보 생성 안함.


대부분 위 사실을 다들 알고 있다.

근데 간과한 것이 하나 있으니 그것은 "INDEX" 다.

append 힌트 사용해서 열심히 insert 해도 인덱스가 있어서 다량의 redo와 index spilt으로 인한 성능 저하는 피할 수 없다.

인덱스를 다 날리고 작업을 하던가 아니면 인덱스를 비활성화 하고 진행하자.


1. alter index table1_idx unusable;

2. alter session set skip_unusable_indexes=true;

3. insert /*+ append */ into table1 select * from table2;

4. alter index big_table1_idx rebuild nologging;


여기서 또 중요한 사실이 하나 있으니 테이블 만들때 PK를 어떻게 만들었냐에 따라 에러를 만나게 될 수도 있다.


SQL> create table test1 (col1 number,

  2  col2 number);


Table created.

SQL> create unique index test1_pk on test1(col1);


Index created.

SQL> alter table test1 add constraints test1_pk primary key(col1);


Table altered.

SQL> alter index test1_pk unusable;


Index altered.

17:38:38 SQL> insert /*+ append */ into test1 select * from test2;


2 rows created.



SQL> create table test1

 2  (col1 number, col2 number, constraint test1_pk primary key(col1));


Table created.

SQL> alter index test1_pk unusable;


Index altered.

SQL> insert /*+ append */ into test1 select * from test2;

insert /*+ append */ into test1 select * from test2

                          *

ERROR at line 1:

ORA-26026: unique index SYS.TEST1_PK initially in unusable state



난 첫번째 방법으로 PK만드는 것을 선호한다.

좀 번거롭긴 하지만 tablespace도 지정할 수 있고, 삭제시 안전 장치도 된다.




'OraclE' 카테고리의 다른 글

dbms_scheduler 변경  (2) 2016.01.04
flashback  (0) 2015.04.27
object 변경시 dependency  (0) 2015.01.06
pid로 port 찾기 (lsof)  (0) 2014.09.17
logminor 로그마이너  (0) 2014.09.05

+ Recent posts