특정 ‘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의 강화 된 클론) -G
를 ag 옵션 으로 수행 할 수 있습니다 .
$ echo foo > bar_wanted.c
$ echo foo > unwanted.c
$ ag -G "bar.*\.c" foo
bar_wanted.c
1:foo
노트:
ag
PCRE 정규 표현식 구문을 사용하므로 regexpbar.*\.c
대신 이어야합니다bar*.c
.- 그
-G
뒤에는 파일 이름으로 해석되므로 옵션이 검색어 앞에 와야합니다.
답변
특정 패턴 만 원하십니까? 아니면 C 소스 파일 만 원하십니까?
모든 C 파일을 원한다면
ack --cc foo
C 파일과 NOT C 헤더 파일을 모두 사용하려면
ack --cc --no-hh foo