ack와 패턴이 일치하는 파일에서만 검색 가능하다는 것을 알고 있습니다. find . -name “bar*.c”

특정 ‘glob’패턴과 일치하는 파일을 통해서만 검색 할 수 있습니다 (예 : “bar * .c”라는 모든 파일에서 foo 검색). 명령

ack foo "bar*.c"

현재 디렉토리에서만 작동합니다.

참고 : find -exec로 가능하다는 것을 알고 있습니다.

find . -name "bar*.c" -type f -exec ack foo {} +

그러나 find는 버전 제어 디렉토리를 건너 뛰지 않기 때문에 작고 간단한 ack 명령을 원합니다.



답변

디렉토리 검색

매뉴얼 페이지에 표시된 개요를 기반으로 디렉토리를 처리 할 수 ​​있지만 스위치를 보면 패턴을 기반으로 파일 만 찾을 수는 없습니다. 이를 위해서는에 참여해야합니다 find. 이 명령 ack에는에서 --files-from=FILE파일 목록을 제공 할 수 있도록 옵션이 포함되어 있습니다 find.

개요

       ack [options] PATTERN [FILE...]
       ack -f [options] [DIRECTORY...]

용법

   --files-from=FILE
       The list of files to be searched is specified in FILE.  The list of
       files are separated by newlines.  If FILE is "-", the list is
       loaded from standard input.

--ignore-file=원하는 것을 줄 수 있지만 실제로 사용하기에는 약간의 고통 이있는 옵션이 있습니다.

   --ignore-file=FILTERTYPE:FILTERARGS
       Ignore files matching FILTERTYPE:FILTERARGS.  The filters are
       specified identically to file type filters as seen in "Defining
       your own types".

특정 유형의 파일 검색

내가 이것을 통해 생각할 수있는 유일한 다른 방법 ack--type스위치 를 사용하는 것입니다 .

   --type=[no]TYPE
       Specify the types of files to include or exclude from a search.
       TYPE is a filetype, like perl or xml.  --type=perl can also be
       specified as --perl, and --type=noperl can be done as --noperl.

       If a file is of both type "foo" and "bar", specifying --foo and
       --nobar will exclude the file, because an exclusion takes
       precedence over an inclusion.

사용 가능한 유형을 확인하려면

$ ack --help-types | grep -E "perl|cpp"

체재. 예를 들어 –type = perl 및 –perl이 모두 작동합니다. -[no] cpp .cpp .cc .cxx .m .hpp .hh .h .hxx-[no] objcpp .mm .h-[no] perl .pl .pm .pod .t .psgi; 첫 줄은 /^#!.*\bperl/-[no] perltest와 일치합니다.

파일 이름 (* .pm, * .pl, * .t 및 * .pod)과 shebang 행을 기반으로 모든 Perl 파일을 찾으십시오.

$ ack -f --type perl
examples/iwatch/iwatch/iwatch
examples/nytprof_perl/bad.pl

모든 C ++ 파일을 찾으십시오.

$ ack -f --type=cpp
Shared/Scanner.h
Shared/Sorter.h
Shared/DicomHelper.cpp
Shared/DicomDeviationWriter.h

bar * .c에서 foo 검색

그렇다면 원하는 것을 어떻게 달성 할 수 있습니까? 글쎄, 당신은 아마 find이것을 사용해야 할 것입니다 :

$ find adir -iname "bar*.c" | ack --files-from=- foo
adir/bar1.c
1:foo
2:foo

adir/dir1/bar1.c
1:foo
2:foo

당신은 또한 사용할 수 있습니다 ack(사용하여 파일 이름에 지정된 패턴과 일치하는 파일을 검색 할 수의 능력 -g <pattern>), 다음의 두 번째 호출이 목록을 통과 ack하여 -x또는 --files-from=-..

사용 -x:

$ ack -g '\bbar.*.c$' | ack -x foo
bar1.c
1:foo
2:foo

dir1/bar1.c
1:foo
2:foo

사용 -files-from=-:

$ ack -g '\bbar.*.c$' | ack --files-from=- foo
bar1.c
1:foo
2:foo

dir1/bar1.c
1:foo
2:foo

두 경우 모두이 정규식을 사용하려는 파일 이름과 일치합니다.

\bbar.*.c$

이것은 줄 끝 앵커를 사용하여 이름이 bar.*c끝나고 끝나는 파일과 일치합니다 . 또한 이름을 사용하여 경계 문자가 있는지 확인합니다 . 또는 예를 들어 경계 문자가 포함 된 파일의 경우 실패합니다 ..c$\b$bar.c%bar.c


답변

파일 형식을 알고 있으면 쉽고, ack은 많은 파일 형식을 알고 있습니다. 예를 들어 C 파일에서만 검색하려면 다음과 같이하십시오.

ack --cc 'string'

그러나 알려진 확장 중 하나가 아닌 경우 고유 한 유형을 정의해야합니다. 이것은 작동해야합니다 :

ack --type-set barc:match:/bar.+\.c/ --barc 'string'

–type-set 및 –barc가 모두 필요합니다.

(메일 링리스트에서도 도움을 준 Andy에게 감사합니다.)


답변

“ack 2의 새로운 기능은 무엇입니까?” http://beyondgrep.com/ack-2.0/

ack 2.0에서는 새로운 -x를 사용하여 ack 호출에서 다른 호출로 파일 이름을 파이프 할 수 있습니다.

ack2 -g -i filepattern | ack2 -x -w searchpattern

나는 그것을 작동시킬 수 없다.

% ack -g "*bar*.c"
Invalid regex '*bar*.c':
Quantifier follows nothing in regex; marked by <-- HERE in m/* <-- HERE bar*.c/ at ack line 314.

따라서 -g에는 정규 표현식이 필요하지만 ‘glob’스타일 옵션을 원합니다 …


답변

이것은 가장 빠르고 안전한 것으로 보입니다.

find . -name '*.c' | ack -x 'some string'

-x STDIN에서 검색 할 파일 목록을 읽습니다.

그러나 파일이 locate데이터베이스 에있을 가능성이 높으면 훨씬 빠릅니다.

locate --basename '*.c' | ack -x 'some thing'

또한 Locate는 구식 정규식을 받아 들일 수 있지만 약간 고통 스럽지만 c파일을 찾는 경우 필요할 수 있습니다.
예 :

locate --basename --regexp '\.\(c\|cpp\|h\|hpp\|cc\)$' |
    ack -x 'some thing'

“c, cpp, h, hpp 또는 cc로 끝나는 모든 파일 이름을 검색하십시오.”


답변

Ack는 glob 스타일 파일 선택을 지원하지 않습니다. 정말로 이것을 그리워하기 때문에 작은 쉘 스크립트 ackg를 만들었습니다 .

#!/bin/sh
# 'glob' support for ack
find -name "$2" -type f -exec ack "$1" {} +

이제 다음 명령을 사용할 수 있습니다 :

ackg foo "bar*.c"

그러나 참고 : 이것은 불행히도 버전 제어 디렉토리 (예 : .git)에서도 검색합니다.


답변

이것은 은색 검색기 (ack-grep의 강화 된 클론) -Gag 옵션 으로 수행 할 수 있습니다 .

$ echo foo > bar_wanted.c
$ echo foo > unwanted.c
$ ag -G "bar.*\.c" foo
bar_wanted.c
1:foo

노트:

  • agPCRE 정규 표현식 구문을 사용하므로 regexp bar.*\.c대신 이어야합니다 bar*.c.
  • -G뒤에는 파일 이름으로 해석되므로 옵션이 검색어 앞에 와야합니다.

답변

특정 패턴 만 원하십니까? 아니면 C 소스 파일 만 원하십니까?

모든 C 파일을 원한다면

ack --cc foo

C 파일과 NOT C 헤더 파일을 모두 사용하려면

ack --cc --no-hh foo