bash script (backup)2021. 1. 28. 13:36

 

반달가면 이글루에서 백업 - bahndal.egloos.com/498262

 

grep 명령을 이용하면 특정한 문자열을 포함하고 있는 파일들이 뭐가 있는지 찾을 수 있다. 훌륭하군!

일단 기본부터 차근차근 살펴보자. grep 명령의 기본 형식은 아래와 같다.

# [옵션]을 적용하여 [파일]의 내용을 검색, [문자열]을 찾음
grep [옵션] [문자열] [파일]

 

이제 아래의 예시를 보자. my_memo.txt 파일에서 abcd 문자열이 포함되어 있는지 검색하고 파일명과 함께 문자열이 포함된 행을 찾아 출력하는 것이다. -H 옵션을 주면 찾은 문자열뿐만 아니라 해당 파일명을 같이 출력해 준다. 파일명과 문자열은 콜론(:)으로 구분된다.

 

grep -H abcd my_memo.txt

my_memo.txt:abcdef

 

문자열은 필요 없고 파일명만 확인하고 싶다면 아래와 같이 -l 옵션을 추가하자.

 

grep -Hl abcd my_memo.txt

my_memo.txt

 

자, 이제 특정 디렉토리와 그 하위 디렉토리에 있는 여러개의 파일들 중에 특정한 문자열을 포함한 파일이 있는지 찾고 파일명을 확인해 보자. -r 옵션(recursive)을 이용하고 파일 대신 디렉토리를 지정하면 된다. 아래의 예시는 ~/Documents 디렉토리의 모든 파일을 검색, 내용에 abcd가 포함된 파일 찾아 파일명을 출력하는 경우이다.

 

grep -Hlr abcd ~/Documents

 

만약 특정 파일만 골라서 확인하고 싶다면 --include 옵션을 추가한다. 아래의 예시는 확장자가 txt인 파일만 대상으로 검색하는 경우이다.

 

grep -Hlr --include=*.txt abcd ~/Documents txt

 

파일 중에 v로 시작되는 파일은 제외하고 검색하려면 여기에 --exclude 옵션을 추가.

 

grep -Hlr --include=*.txt --exclude=v* abcd ~/Documents

 

 

Posted by 반달가면

댓글을 달아 주세요

bash script (backup)2020. 11. 16. 17:29

 

반달가면 이글루에서 백업 - bahndal.egloos.com/451182

 

grep의 문자열 검색 기능을 매우 강력하지만 기본적으로 특정 문자열이 "포함된" 행을 찾아내는 것이다. 특정 문자열에 정확히 일치하는 항목이 있는지를 찾으려면 일이 약간 복잡해 진다.

 

일단 my_file.txt 파일의 내용이 아래와 같다고 생각해 보자.

 

john

john_smith

my name is john smith

my name is john_smith

 

일단 포함 여부가 아니라 행 전체가 일치하는 경우를 찾아야 한다면 -x 옵션으로 간단히 해결할 수 있겠다.

 

cat my_file.txt | grep -x "john"

john

 

또는 정규표현을 이용해도 된다. j로 시작되고(^j) 그 다음에 ohn이 있고 마지막에 n으로 끝나게(n$) 되는 문자열을 찾는 것이다.

 

cat my_file.txt | grep "^john$"

john

 

위 방법은 탭이나 공백이 포함되어 있을 경우에 문제가 될 수 있다. 예를 들어 my_file.txt의 john이라는 행이 john[공백] 이런 식이면 위의 방법으로는 검색이 안된다. 아니면 공백이 있다는 것을 미리 알고 grep의 인자에 반영해야 한다.

 

cat my_file.txt | grep -x "john "

 

탭이 포함된 경우라면 이런 식으로 반영하긴 어렵고 awk를 써야 한다. (탭이 포함된 문자열 검색은 이전 게시물을 참고하자.)

 

그렇다면 행 중간에 있는 특정 문자열을 정확하게 찾으려면 어떻게 할 것인가? 위의 my_file.txt에서 john_smith는 제외하고 john만 찾고 싶은 경우인데, grep의 정규표현과 이전에 게시했던 다중 문자열 검색 방법을 활용해 볼 수 있다.

 

정규표현 중에 [[:graph:]]라는 것이 있다. 화면에 표시할 수 있는 모든 문자(영문 대소문자 + 수자 + 특수기호)를 지칭한다. 공백은 제외된다. 공백도 포함하는 표현은 [[:print:]]이다.

 

자, 이제 아래의 예를 보자.

 

cat my_file.txt | grep "john" | grep -v "[[:graph:]]john\|john[[:graph:]]"

john

my name is john smith

 

우선 john이 포함된 행을 골라낸 후, john 앞에 다른 문자가 붙은 경우([[:graph:]]john) 또는(\|) john 뒤에 다른 문자가 붙은 경우(john[[:graph:]])를 -v 옵션으로 제외시킨 것이다.

 

 

Posted by 반달가면

댓글을 달아 주세요

bash script (backup)2020. 11. 9. 17:11

 

반달가면 이글루에서 백업 - bahndal.egloos.com/442412

 

grep을 이용한 문자열 검색에서 정규표현(regular expression)은 매우 유용하지만 이걸 비활성화해야 될 경우가 있다. 일단, 찾고자 하는 문자열이 명시적으로 정해져 있다면 문제는 간단하다. 문자열을 작은따옴표로 감싸거나, 정규표현에 사용되는 [, -, ] 등의 기호 앞에 역슬래시(\) 기호를 사용하면 된다. 아래의 예시를 보자.

 

# a부터 z까지, 즉 영소문자를 검색하는 정규표현

cat my_file.txt | grep "[a-z]"

 

# 검색하려는 문자열 자체가 '[a-z]'인 경우

cat my_file.txt | grep '[a-z]'

cat my_file.txt | grep "\[a\-z\]"

 

그러나 만약 변수에 할당된 문자열에 정규표현에 사용되는 기호가 포함되어 있을 경우엔 어떻게 할 것인가? 이 경우엔 정규표현으로 해석이 되지 않도록 -F 옵션을 사용하면 된다.

 

str="[a-z]"

cat my_file.txt | grep -F "$str"

 

이렇게 해도 해결이 안되는 경우가 있는데, 검색하고자 하는 문자열이 하이픈(-)으로 시작되는 경우이다. 이 경우에는 -e 옵션을 같이 사용하자.

 

str="-[a-z]"

cat my_file.txt | grep -Fe "$str"

 

파일에서 문자열을 읽어서 변수에 할당하고 이 변수가 grep 명령어에 사용되는 경우, 문자열에 특수문자들이 포함될 가능성이 있다면 -Fe 옵션을 추가해 주자.

 

 

Posted by 반달가면

댓글을 달아 주세요

bash script (backup)2020. 10. 22. 12:17

 

반달가면 이글루에서 백업 - bahndal.egloos.com/418681

 

텍스트 파일에서 2개 이상의 문자열을 검색하는 방법이다.

(A and B) 일단 A라는 문자열과 B라는 문자열이 모두 포함된 행을 찾는 것은 간단하다. 파이프(|)를 이용해서, A가 포함된 뿐을 골라낸 후에 거기서 B를 골라내면 된다.

 

cat file.txt | grep A | grep B

 

(A or B) A 또는 B가 포함된 행을 찾으려면 A와 B를 파이프(|) 기호로 연결하면 된다. 연산자로 인식하도록 역슬래시(\)를 붙여준다.

 

cat file.txt | grep "A\|B"

 

또는 egrep 명령을 활용해도 된다. 작은따옴표(')와 괄호를 이용한다.

 

cat file.txt | egrep '(A|B)'

 

만약 shell script에서 변수에 할당된 문자열을 사용하려고 한다면 egrep으로는 어렵고 앞에 언급한 파이프 기호를 이용해야 한다.

 

str_a="1st string"

str_b="2nd string"

cat file.txt | grep "$str_a\|$str_b"

 

Posted by 반달가면

댓글을 달아 주세요

bash script (backup)2020. 10. 15. 15:28

 

반달가면 이글루에서 백업 - bahndal.egloos.com/332093

 

파일을 지우려면 우선 해당 파일명을 찾아야 한다. ls -l 명령으로 timestamp가 표시되도록 한 후 awk로 파일명을 골라내자.

예를 들어 5월 24일이 찍힌 파일을 찾으려면 이렇게 할 수 있다.

ls -l | grep "^\-r" | grep "May 24" | awk '{print $9}'

퍼미션 표시에서 (디렉토리나 링크가 아닌) 파일은 -rwxr--r-- 이런 식으로 나올 테니 "-r"로 시작하는 항목만 grep으로 고른다.('-'가 grep에서 연산자로 해석되지 않도록 '\-' 이런식으로 쓰자)

거기서 원하는 timestamp가 있는 항목을 골라낸다.

거기서 파일명이 표시되는 위치인 9번째 항목(field)을 awk 명령으로 골라낸다.

자, 이제 지워야겠으니 위의 명령을 역따옴표(`)로 묶어서 rm 명령에 넘기자.

rm `ls -l | grep "^\-r" | grep "May 24" | awk '{print $9}'`

 

 

Posted by 반달가면

댓글을 달아 주세요