System/Common

grep - 특정 단어 빼고 출력

linuxism 2013. 3. 8. 10:07


보통 vi 로 작업하시는 분들은 터미널로 검색을 많이 하십니다.


원하는 결과를 얻기 위해서는 여러가지 검색 옵션을 사용하게 되는데요


너무 평이한 검색어를 사용함으로써 원치 않는 결과는 좀 빼고 보면 좋겠다 싶을때가 있습니다.


이럴때 사용하는 옵션이 있는데 의의로 모르는 분들이 만습니다.


간단히 grep 의 옵션을 살펴봅니다.


root@boggle70-desktop:linux# grep --help

사용법: grep [옵션]... 패턴 [파일]...

각 파일 및 표준 입력에서 패턴 찾기

패턴은 기본값으로 기본 정규 표현식(BRE)입니다.

예제: grep -i 'hello world' menu.h main.c


정규식 선택과 해석

  -E, --extended-regexp     확장된 정규 표현식으로 된 패턴 (ERE)

  -F, --fixed-strings       개행 문자로 구분된 고정 길이 문자열로 된 패턴

  -G, --basic-regexp        기본 정규 표현식으로 된 패턴 (BRE)

  -P, --perl-regexp         펄 정규 표현식으로 된 패턴

  -e, --regexp=PATTERN      패턴을 이용해서 찾기

  -f, --file=FILE           파일에서 패턴을 가져옴

  -i, --ignore-case         대소문자 구분 안 함

  -w, --word-regexp         전체 단어에 대해서만 패턴 비교

  -x, --line-regexp         전체 라인에 대해서만 패턴 비교

  -z, --null-data           새 줄이 아닌 0 바이트인 줄 끝 데이터


Miscellaneous:

  -s, --no-messages         suppress error messages

  -v, --invert-match        select non-matching lines

  -V, --version             print version information and exit

      --help                display this help and exit

      --mmap                use memory-mapped input if possible


Output control:

  -m, --max-count=NUM       stop after NUM matches

  -b, --byte-offset         print the byte offset with output lines

  -n, --line-number         print line number with output lines

      --line-buffered       flush output on every line

  -H, --with-filename       print the filename for each match

  -h, --no-filename         suppress the prefixing filename on output

      --label=LABEL         print LABEL as filename for standard input

  -o, --only-matching       show only the part of a line matching PATTERN

  -q, --quiet, --silent     suppress all normal output

      --binary-files=TYPE   assume that binary files are TYPE;

                            TYPE is `binary', `text', or `without-match'

  -a, --text                equivalent to --binary-files=text

  -I                        equivalent to --binary-files=without-match

  -d, --directories=ACTION  how to handle directories;

                            ACTION is `read', `recurse', or `skip'

  -D, --devices=ACTION      how to handle devices, FIFOs and sockets;

                            ACTION is `read' or `skip'

  -R, -r, --recursive       equivalent to --directories=recurse

      --include=FILE_PATTERN  search only files that match FILE_PATTERN

      --exclude=FILE_PATTERN  skip files and directories matching FILE_PATTERN

      --exclude-from=FILE   skip files matching any file pattern from FILE

      --exclude-dir=PATTERN directories that match PATTERN will be skipped.

  -L, --files-without-match print only names of FILEs containing no match

  -l, --files-with-matches  print only names of FILEs containing matches

  -c, --count               print only a count of matching lines per FILE

  -T, --initial-tab         make tabs line up (if needed)

  -Z, --null                print 0 byte after FILE name


Context control:

  -B, --before-context=NUM  print NUM lines of leading context

  -A, --after-context=NUM   print NUM lines of trailing context

  -C, --context=NUM         print NUM lines of output context

  -NUM                      same as --context=NUM

      --color[=WHEN],

      --colour[=WHEN]       use markers to highlight the matching strings;

                            WHEN is `always', `never', or `auto'

  -U, --binary              do not strip CR characters at EOL (MSDOS)

  -u, --unix-byte-offsets   report offsets as if CRs were not there (MSDOS)



아 상당히 많은 옵션이 있습니다. (너무 당연한가요?)

몇몇 중요한 옵션고 함께 살펴봅니다.

먼저 
r 옵션은 recursive 옵션입니다.  서브 디렉토리까지 뒤진다는 거죠
n 옵션은 라인 넘버를 출력해 주는 옵션입니다.
r 옵션은 invert 옵션입니다.
            지정한 검색어를 포함하지 않는 라인만 출력하라는 것입니다.

r 옵션은 파이프를 이용한 검색에서 효과적입니다.
즉 내가 검색한 단어가 너무 많이 출력될때... 특히 ctag 와 같은 파일이 함께 있을때
귀찮을 정도로 그곳에서 많이 뜨게 됩니다.

리눅스 커널 디렉토리에서 ctag 를 만든후 grep 으로 검색하면 ctag 에서 저장된 단어들이 주욱 나옵니다.

root@boggle70-desktop:linux# grep -rn sk_buff

이렇게 하면 엄청난 검색어를 보이게 됩니다.
하지만 

root@boggle70-desktop:linux# grep -rn sk_buff ./ | grep -v tags

이렇게 하면 tags 라는 단어를 포함한 라인은 모두 제거됩니다.

커널의 include 디렉토리에서 sk_buff 의 선언을 찾는다고 하고 시도합니다.

grep -rnw sk_buff ./include/ | grep -v tags | grep -v cscope | grep -v extern | grep -v static | grep -v "*"

첫번째는 r 서브디렉토리 검색옵션 + 라인 넘버 출력 + 단어 일치 옵션
두번째는 검색결과에서 tags 제거
세번째는 검색결과에서 cscope 제거
네번째는 검색결과에서 extern  제거
다섯번째는 검색결과에서 static  제거
여섯번재는 검색결과에서 포인터를 나타내는 * 제거

그러면 결과가 20개 안쪽에서 함수의 선을 찾을수 있습니다.

물론 저는 ctags 를 만들어 

vi -t sk_buff    와 같이 해서 

태그가 정의된 위치에서 파일을 열어 해당 위치에 커서를 놓아주는 -t
vim 의 옵션을 씁니다.


출처 - http://forum.falinux.com/zbxe/index.php?document_srl=550758&mid=lecture_tip