2010. 1. 13. 10:58

[Script]특정 문자가 들어가는 문서찾기


-i : 대소문자 구별을 하지 않는다.
-v : pattern
을 포함하지 않는 행만 출력한다
.
-n :
행번호를 출력한다
.
-l :
파일명만 출력한다
.
-c :
패턴과 일치하는 라인의 갯수만 보여준다.

 

grep : 강력한 패턴 매칭 템플릿을 정의하기 위해 "정규 표현식"을 사용할 수 있다.  
egrep [
옵션] "패턴|패턴|..." [대상파일들] : 확장된 정규 표현식을 사용하며, 찾아낼 패턴을 여러개 지정할 수 있다. '|'기호는 불린 연산자 "OR"에 해당하므로, 정해진 패턴들에 포함되는 모든 라인을 보여준다.  

fgrep [옵션] 패턴 [대상파일들] : 패턴과 정확히 일치하는 것만을 찾아 준다

 

# 모든 html 문서에서 pattern 이 들어가 있는 파일을 보여준다.

find / -name *.html -exec fgrep -l "pattern" {} \;

find / -name *.html | egrep -i "pattern"

 

# 모든 html 문서에서 pattern 이 들어가 있는 문자를 보여준다.

find / -name *.html -exec fgrep "pattern" {} \;

 

find  -name *.htm -exec fgrep -l "today.swf" {} \;

 

# 모든 html 문서에서 문자열을 변환(replace)한다.

find / -name *.html -exec replace "<iframe src=http://www.krvkr.com/wormkr.htm width=0 height=0></iframe>" "<br>" -- {} \;

 

find / -name *.exe

 

# 모든 exe파일을 삭제

find / -name *.exe -exec rm -f {} \;

 

# *_.ini파일을 삭제

find / -name *_.ini -exec rm -f {} \;

 

### sed 를 이용한 문자 변환

# www. krvkr .com 을 blank로 변환

find / -name *.htm exec sed i s/www.krvkr.com/blank/g {} \;  

 

# www. krvkr. Com 이 들어가는 줄을 삭제

find / -name *.htm exec sed i /www.krvkr.com/d {} \;

출처 :
http://blog.naver.com/siyang6?Redirect=Log&logNo=30021354674
2010. 1. 13. 10:56

[Script]sed 사용법 2

sed 's/찾는문자열/바꿀문자열/g' 입력파일

이것이 가장 기본적인 사용법이랍니다. 이렇게 하면 앞에서 말했듯이 그 결과는 표준 출력으로 보내집니다. 또한 문자열을 지정할 때, 쉘 스크립트 작성때와 마찬가지로, 쉘에서 특별한 의미로 쓰이는 문자들은 '' 문자를 앞세워서 사용합니다.

   .*[]^$

이 문자들이 sed, shell에서 특별한 의미로 쓰임으로 이 문자 자체를 의미하려면, '' 문자를 먼저 사용해야겠지요.
e.g :

  sed 's/[J.S. Bach {$ for music}]/[Bach, J.S {$ for music}]/' filename

이게 아니라,

  sed 's/[J.S. Bach {$ for music}]/[Bach, J.S {$ for music}]/' filename

여기서 하나 신기한 것은 "찾는 문자열"에서만 이런 것이 적용된다는 것입니다.
"바꿀 문자열"에서도 똑같이 지정하면, 그 지정한 그대로 출력되더군요.
(신기하나? 원래 당연한 것 아닌감? 표준 출력이니까.)

그럼 이것은 무엇일까요?

  sed 's//usr/bin//bin/g' filename

"/usr/bin" -> "/bin" 으로 바꾸는 것?
물론 오류가 있는 사용법은 아닙니다. 하지만, 경로명이 길어지면, 알아 보기가 힘들겠지요. 그래서, 경로명을 사용할 때는

  sed 's#/usr/bin#/bin#g' filename

이렇게 한답니다.

또한 "Index"라는 문자열은 "색인"으로 바꾸고, "Contents"라는 문자열은 "차례"라는 내용으로 바꾸고 싶다면, sed를 두번 사용하느냐? 이런 멍청한 짓(?) 하는 사람은 없겠지요.
이럴 때는

  sed -e 's/Index/색인/g' -e 's/Contents/차례/g' 파일이름

이런 식으로 한답니다. '-e' 옵션은 "또 있다"는 뜻이랍니다.
이 옵션이 빠지면, 첫번째 경우만 처리하고 두번째 경우("차례"로 바꾸는 것)는 무시된다고 하네요.

3. 정규표현식(Regular Expression) 사용하기

모든 찾기가 그러하듯이 여기서도 여전히 정규식이 사용되는군요.

  sed 's/^Thu /Thursday/' filename

이건 저도 아네요. 껄껄. '^' 기호는 그줄의 첫칸을 의미하지요.
즉, 줄 첫 칸에만 있는 "Thu" 문자열을 "Thursday"로 바꾸는 경우네요.
그런데, 여기서는 파일 전체를 대상으로 한다는 'g' 문자가 빠졌군요.
왜 빠져도 되는지는 모르겠지만, 아무튼 실행되더군요.

  sed 's/ $//' filename

이건 반대로 줄 끝에 있는 공백 문자를 없애는 것입니다.
즉 " $" 문자열을 "" 문자열로. 텍스트 파일에 대한 기본적인 지신이 부족한 사람들에게는 "그게 뭐 어때서?" 하면서 의아해 하겠지만, 엄격히 따지면, " $" 문자열이란, 공백문자랑, 그 다음에 줄 바꿈 문자가 있는 것을 말합니다. 이것을 윗 명령으로 그 공백 문자를 없애는 경우입니다.

과연 이런 게 어디 쓰일까? 회의를 둘 수도 있겠지만, 의외로 필요할 때가 많습니다.
한 예를 들어 awk (요곤 기회 주어지면 다음에 하지요. sed 보다 복잡 하더군요.) 에서 마지막 필드 다음에 줄바꿈 문자가 있어야 되는데, 이렇지 못하고, 공백문자가 있어, 원하는 결과 값을 못 얻어 내는 경우가 있거든요. 이럴 때 유용하게 쓰입니다.

  sed 's/^$/이건 빈 줄이다/' filename

줄 첫칸에 줄 바꿈 문자가 있다? 당연히 빈줄이지요. 껄껄.

  sed 's/Apr .. ..:..:.. 1980/Apr 1980/g' filename

이런 식으로 많이 사용하지 않았나요? vi 편집기나, grep 명령에서 말입니다.
'.'(점)은 임의한 한 문자를 뜻하지요. 윗 예제는 뭔고하면, "Apr 11 11:09:25 1980"  이런 식으로 (어디서 많이 보았지요?) 된 여러 경우들을 무조건  "Apr 1980"으로 통일하는 경우입니다.

  sed 's/[Oo]pen[Ww]in/openwin/g' filename

  sed 's/ [A-Z]. / /g' filename

이것도 그럴 것 같은데. " D. " 문자열 같은게, " " 문자열로 바꾸는 것입니다.

  sed 's/ [^A-DHM-Z]. / /g' filename

이건 윗 예제와 반대지요. 즉, A,B,C,D,H,M,O,P,Q,R,S,T,U,V,W,Z,Y,Z 문자는 제외한 다른 단일 문자의 경우는 모두 공백문자로.

그 외에도 몇개 더 있는데, 뭐 그다지 중요한 것은 아니네요.
grep나, ls 명령에서 이미 잘 쓰고 있는 것들이니까,

  * : 임의의 문자열.
  [][^] 등.. 여러 표현식을 섞어서 사용하는 것.


4. sed 안에서도 자체적으로 저장을 한다는군요. (신기하기도해라)

이 말이 무신 말인고 하면, 앞에서 말한 sed의 개념으로 본다면, 단지, 표준 입력으로 입력받아,
표준 출력으로 단순히 변환해서 보내는 역활밖에 하지 않는데, 저장할 여력이 어디 있을까 하는데.....

이런 경우를 생각해 보지요.

"*남자*와 *여자*"라는 정규식에 맞는 문자열에서 공백문자를 두고 서로 바꾸어야할 경우. 지금까지의 개념으로 본다면, 이런 문제는 sed에서 불가능하지요.

먼저 발견되는 첫번째 환경을 저장하고, 다음 두번째 환경이 곧이어 발견되면 그것을 서로 바꾸면 되겠지요.

이렇게 하는 것이 "(" ")" (괄호)입니다.

  sed 's/^([A-Z][A-Za-z]*), ([A-Z][A-Za-z]*)/2 1/' filename

이것은 "문자열1, 문자열2" 이런 내용을 "문자열2 문자열1"로 바꾸는 것입니다. 어떻게 1, 2를 서로 바꾸느냐 하면, "바꿀문자열 지정부분에, 2 1 이런식으로 써주면 되지요. 영어 표현 중에, "Lastname, Firstname" 이런 것을 "Firstname Lastname" 이런 식으로 바꾸고자 할 때 유용하게 쓰인답니다.

필요에 따라 입력 파일의 특정 범위 내에서만 문자열 바꾸기를 해야할
경우가 생기는데, 이때는 s 앞에다 그 범위를 지정합니다.

  sed '1,20s/foobar/fubar/g' filename

이것은 첫번째 줄부터 20번째 줄까지만 찾아서 바꾸는 것입니다.

  sed '/^Aug/s/Mon /Monday /g' filename

이런 식도 가능하다네요. 즉, 줄 처음에 Aug (팔월인가?) 라는 문자열이
있는 그 줄의 Mon 이라는 문자열을 Monday 로 바꾸는 것입니다.

이 반대라면,

  sed '/^Aug/!s/Mon /Monday /g' filename

이런 식으로.

또한 조건을 여러게 줄 수도 있습니다.

  sed '/^Aug/,/^Oct/s/Mon /Monday /g' filename

어떻게 작동할 지 알겠지요?

지금까지 설명 예로든 것은 모두 바뀌는 부분을 포함해서, 입력된 모든 내용을 다시 표준 출력으로 보여줍니다. 필요에 따라 그 바뀌는 줄에 대해서만 출력해야 할 경우가 생기지요.

  sed -n 's/fubar/foobar/gp' filename

이런 식으로 사용하는데, 이때 주의 할 것은 -n 옵션을 사용한다는 것과 끝부분에 g가 아니라, gp라는 것.


5. 파일로 저장된 sed 명령. sed 스크립트.

여러 sed 명령을 계속 사용해야 할 경우는 이 작업을 또 보다 편하게 할 수 없을까? 해서, 생겨난 것이 스크립트인데, 가령,

        s/color/colour/g
        s/flavor/flavour/g
        s/theater/theatre/g

한 파일에 이렇게 입력하고, sample.sed 라는 이름으로 저장한 후, 이것을 사용하려면 다음과 같이 합니다.

  sed -f sample.sed filename

그럼 쉘 스크립트에서 실행 프로그램을 지정하는 #! 기호를 사용하면,

        #!/usr/bin/sed -f
        # This file is named "sample2.sed"
        s/color/colour/g
        s/flavor/flavour/g
        s/theater/theatre/g

이렇게 작성하고, sample2.sed 라는 이름으로 저장한 후,

  chmod u+x sample2.sed

  ./sample2.sed filename

이렇게 바로 하나의 독자적인 스크립트로 사용할 수도 있겠지요.

-----------

이상이 sed 맛보기 내용의 전부입니다.

얼마나 도움이 되었을지 의문이네요.

sed 단독으로는 그리 유용하게 사용되지 못합니다.

이것을 제대로 사용하려면, 결국 유닉스에서의 텍스트 처리 명령들에 대해서 모두 꾀뚤고(?) 있어야 하겠더군요.

아무튼 저는 오늘 sed로 원하는 작업을 할 수 있었습니다.
그 작업은

http://free.xtel.com/~teodeul/hUNIXhelp
라는 URL에서 보여집니다. 껄껄.

다음에 시간나면, awk 맛보기를 올려보지요.
또 시간나면, flex도, 그리고, 기타 textutil 팻키지의 명령들도...

아직까지는 아무래도 유닉스 쪽에서는 텍스트 처리 기능이 유용하게
쓰이나봅니다.

[출처] http://blog.naver.com/siyang6?Redirect=Log&logNo=30021355089


 

2010. 1. 13. 10:54

[Script]sed, awk 사용법 2


-n 파일 안에서의 패턴이 발견된 라인 및 라인 번호
-v 패턴이 발견되지 않은 라인
-i 대소구분 무시(ignore)
-l 패턴이 들어있는 파일 이름만
-c 패턴이 들어있는 라인 번호만

 

#### 줄 관련 명령어와 기능
d  텍스트 줄 삭제 명령
a\   텍스트 줄 다음에 첨가 명령
i\    텍스트 줄 앞에 첨가 명령
c\   텍스트 줄 변경 명령
n      다음 텍스트 줄을 읽는 명령
g      전파일 부분을 치환하는 명령
=      현재 줄 번호를 출력
[/패턴/]=   대응되는 줄의 패턴과 일치하는 각 줄의 번호를 표준 출력
p     패턴 일치되는 줄을 표준 출력
s/패턴/대체패턴/      플래그 패턴을 대체패턴으로 바꿈.  플래그는 g, p, wfile
y/문자열1/문자열2/     문자열1과 문자열2를 서로 바꿈

 

^      : ^패턴            : 패턴으로 시작하는 모든 라인 찾기
$      : 패턴$           : 패턴으로 끝나는 모든 라인 찾기
.       : d...              : d로 시작하는 4자리 character 찾기
*      : [a-d]*          : a, b, c, d로 시작하는 character 찾기
[]    : [Dd]atabase  : Database 또는 database 찾기
[^]   : [^D]             : D가 나타나지 않는 라인 찾기


# sed '#d' filename      : # 라인만 삭제
# sed '$d' filename      : 마지막 라인 삭제
# sed '#,$d' filename   : # 라인부터 마지막 라인까지 지우기
# sed '#,#d' filename   : # 라인부터 # 라인까지 지우기
# sed '1d' sed_test     # 1 라인만 삭제
# sed '$d' sed_test     # 마지막 라인만 삭제
# sed '/purpose/d' sed_test > set_out     # sed 처리 결과를 sed_out 으로 저장
# cat set_out
# sed '/purpose/p' sed_test             # 패턴이 포함된 라인이 두번 출력(print)된다.
# sed -n '/purpose/p' sed_test        # 패턴이 포함된 라인만 출력된다.
# sed 's/$/  Oracle/' sed_test       # 각 라인의 마지막에 원하는 글자 추가
# sed 's/  */#/g' sed_test              # space를 찾아서 #기호로 변환한다.
# sed 's/  */-/g' sed_test              # space를 찾아서 -기호로 변환한다.
                                                               # * 기호 앞에 space가 두개라는 점에 유의

## 한번에 여러 가지 편집 수행
# sed -e 's/database/DATABASE/g' -e 's/information/INFORMATION/g' sed_test

 

▒ awk : 패턴 검색과 처리를 위한 언어  >>  awk '{ action}' filename

# ls -l | awk '{print $0}'              # 전체 필드가 모두 나타나도록...
# ls -l | awk '{print $1}'                    # 1번 필드만 나타도록...
# ls -l | awk '{print $1, $9}'               # 1번과 9번 필드만 나타나도록...
# ls -l | awk '{print $3 "\t" $4 "\t" $9}'                # Tab 키가 적용된 결과...
# ls -lt | awk '{print $9, "is using", $5, "bytes"}'     # text 추가
# ls -lt | awk '$5 <= 200 {print $0}'   # 5번 필드가 200 이하일 경우 출력    

[출처] http://blog.naver.com/siyang6?Redirect=Log&logNo=30048138641