bash script (backup)2021. 5. 10. 15:36

 

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

 

조금 생각해 보면 금방 알 수 있는 내용이긴 하지만, 최근 쇠퇴하고 있는 기억력을 절감하는 중이라 적어 두기로 했다.

grep 명령을 이용해서 특정 문자열을 검색하고 해당 문자열을 포함한 파일명을 찾는 자세한 방법은 이전에 올린 게시물을 참고하자.

 

일단 아래의 예시를 보자. -H 옵션을 사용하면 결과가 파일명:문자열 형태로 출력된다. -r(recursive) 옵션은 지정한 디렉토리와 그 하위 디렉토리에서 검색하기 위한 것이다.

# /home/john/Documents 디렉토리와 그 하위 디렉토리에서 abcd를 포함한 파일명과 해당 문자열을 출력
grep -Hr abcd /home/john/Documents

/home/john/Documents/my_file.txt:abcdefg

/home/john/Documents/my_file2.dat:abcde_xyz

 

다단계로 복잡한 검색을 하면서 파일명도 확인하려고 한다면, 일단 파일명을 확인하기 위한 -H 옵션으로 검색을 하고, 나머지 복잡한 검색을 파이프(|)를 이용해서 뒤쪽으로 이어주면 된다. 아래의 예시를 보자.

 

# abcd가 포함된 파일명과 해당 문자열을 검색한 후에 xyz가 포함된 항목을 제외(-v 옵션)

grep -Hr abcd /home/john/Documents | grep -v xyz

/home/john/Documents/my_file.txt:abcdefg

 

파이프 이후에는 -H 옵션이 의미가 없어진다. 입력이 파일이 아니라 이전 명령의 출력값이 되기 때문이다. 아래와 같이 사용하면 파일명을 확인할 수 없다.

 

# 이렇게 하면 파일명 확인 불가능

grep -r abcd /home/john/Documents | grep -H -v xyz

 

Posted by 반달가면

댓글을 달아 주세요

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 반달가면

댓글을 달아 주세요