[shell] 다양한 문자열 검색 방법
문자열찾기 방법 1 – 영어만 주로 가능
# grep -rw “찾는문자열” ./
문자열찾기 방법 2 – 대/소문자 구분 안하고 검색
# grep -i -l “찾는문자열” * -r 2> /dev/null
문자열찾기 방법 3 – 한글, 영어 모두 가능
# find . -exec grep -l “찾는문자열” {} \\; 2>/dev/null
문자열찾기 방법 4 – 한글,영어, 대소문자 안가리고 검색
# find . -exec grep -i -l “찾을문자열” {} \\; 2>/dev/null
문자열찾은 후 치환
# find . -exec perl -pi -e ‘s/찾을문자열/바꿀문자열/g’ {} \\; 2>/dev/null
파일명 찾기
# find / -name 파일명 -type f
파일명 찾기(대소문자 구별없음)
# find / -iname 파일명 -type f
디렉토리 찾기
# find / -name 파일명 -type d
디렉토리 찾기(대소문자 구별없음)
# find / -iname 파일명 -type d
하위 디렉토리에 모두 포함하여 문자열 찾기
grep -rl [문자열] *
r 옵션이 없다면
find . * -exec grep -n [문자열] {}\\; -print
더 짧고도 효과적인 방법
grep “string”‘find . -type ‘
그런데 이는 조건에 맞는 파일의 개수가 많아지면 쉘의 명령행 버퍼의 범위를 벗어나므로 문제가될 소지가 있다. 명령행 버퍼의 오버플로우를 방지하기 위해선 다음과 같이 하면 된다.
find . -type f | xargs grep “string”
그런데 이 방법은 파일 이름에 공백이 들어갈 경우 문제가 생길 수 있다. 그럼 다음과 같이 해보자.
find . -type f -print0 | xargs -0 grep “string”
find는 심볼릭 링크된 디렉토리에 대해서는 기본적으로 검색을 실시하지 않으니 -follow옵션을 사용해야할 경우도 있다는 것을 알아둔다.
명령행 버퍼오버플로우를 방지하는 방법은 다음과 같은 방법도 있다.
find . -type f -exec grep -l”string” {}\;
grep에서 ‘-l’옵션은 string을 포함하는 파일명을 나타내준다. 이런 검색을 특정 파일들에 대해서 행하기 위해서는 -type와 -name옵션을 쓸 수 있다.
find . \(-type f -name “*\.html”\) -exec grep -l “string” {}\;
이것은 html의 확장자를 가지는 모든 파일에 대해서 “string”을 포함하는지 알아보고 포함하고 있는 파일명을 출력해준다.
위의 방법들은 “어떻게 서브디렉토리에 있는 파일들에 대해서 grep을 실행해줄 수 있는가?”하는 문제에 관한 여러 가지 방법들은 매우 유용하긴 하지만 검색을 실시하는 디렉토리에 바이너리 파일이 있을 경우에는 터미널을 제어하지 못하는 문제가 생길 수 있다. 왜냐하면 바이너리 파일의 몇몇 제어 문자들(Control Characters)이 터미널을 그래픽 모드로 바꿔놓을 수 있기 때문이다. 물론 이렇게 되었을 경우 터미널을 다시 바로잡는 방법이 있긴 하지만 아무래도 가장 좋은 방법은 그러한 일이 없도록 처음부터 방지하는 것이 가장 좋을 것이다.
이제 화면에 찍혀나올 수 없는 문자들을 모두 없애보자. 어쨌든 읽을 수는 없지만 다음과 같은 명령을 내려보라.
sed -e ‘s/[^-~][^-~]*//g’
이 명령은 화면에 출력될 수 없는 (제어) 문자들을 그냥 스페이스들로 바꿔 버린다. 이 명령은 파이프를 이용하여 쉽게 다른 명령어들과 결합해서 사용할 수 있다. 여기 간단한 쉘 스크립트가 있다. 이것을 grepfind라고 이름붙여서 사용할 수 있다.
#!/bin/sh
#save this in a file called grepfind and do a “chmod 755 grepfind”
#
if test $@ = 0 -o “$1” = “-h” -o “$1” = “-help” ; then
echo ‘grepfind ─ recursively descends directories and egrep all files ‘
echo
echo ‘Usage: grepfind [-help][-h](start_directory] egrep_search_pattern’
echo
echo ‘The surrent directory is used as start_directory if parameter’
echo ‘start_directory is omitted. The search is case insensitive.’
echo ‘Multiple occurrences of control characters are replaced by a single’
echo ‘space. This makes it possible to grep around in files that contain’
echo ‘binary data and strings without setting the terminal accidently’
echo ‘to graphics mode.’
echo
echo ‘Example : grepfind/home “hello world”
else
if [“$2” = “” ];then
find . -type f -exec egrep -i “$1” /dev/null {} \;|sed -e ‘s/[^-~][^-~]*//g’
else
if [-d “$1” ] ;then
find $1 -type f -exec egrep -i “$2” /dev/null {} \;|sed -e ‘s/[^-~][^-~]*//g’
else
echo “ERROR: $1 is not a directory”
fi
fi
fi
#_END_OF_grepfind