확인 검색은 특정 "glob" 패턴과 일치하는 파일에 의해서만 수행될 수 있습니다(예: "bar*.c"라는 이름의 모든 파일에서 foo 검색). 주문하다
ack foo "bar*.c"
현재 디렉터리에만 적용됩니다.
참고: find -exec를 사용하면 가능하다는 것을 알고 있습니다.
find . -name "bar*.c" -type f -exec ack foo {} +
하지만 find는 버전 제어 디렉터리를 건너뛰지 않기 때문에 작고 간단한 ack 명령을 원합니다.
답변1
카탈로그 검색
매뉴얼 페이지에 표시된 개요에 따르면 예라고 말하고 싶습니다. 디렉터리를 처리할 수 있지만 스위치를 보면 패턴을 기반으로 파일을 찾을 수는 없습니다. 그러기 위해서는 군대에 입대해야 합니다 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이 모두 유효합니다. --[아니요]cpp .cpp .cc .cxx .m .hpp .hh .h .hxx --[아니요]objcpp .mm .h --[아니요]perl .pl .pm .pod .t .psgi; 라인은 /^#!.*\bperl/ --[no]perltest .t와 일치합니다.
예
파일 이름(*.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
답변2
파일 유형을 알고 있으면 쉽고 ack는 많은 파일 유형에 대해 알고 있습니다. 예를 들어 C 파일에서만 검색하려는 경우 다음을 수행할 수 있습니다.
ack --cc 'string'
그러나 알려진 확장 중 하나가 아닌 경우 고유한 유형을 정의해야 합니다. 이것은 작동합니다:
ack --type-set barc:match:/bar.+\.c/ --barc 'string'
--type-set 및 --barc가 필요합니다.
(메일링 리스트에도 도움을 준 Andy에게 감사드립니다.)
답변3
이것이 가장 빠르고 안전한 것 같습니다.
find . -name '*.c' | ack -x 'some string'
-엑스 STDIN에서 검색할 파일 목록을 읽습니다.
그러나 파일이 데이터베이스에 있으면 locate
더 빠릅니다.
locate --basename '*.c' | ack -x 'some thing'
Locate는 구식 정규 표현식도 허용하는데 이는 약간 번거롭지만 파일을 찾고 있다면 c
필요할 수도 있습니다.
예를 들어
locate --basename --regex '\.\(c\|cpp\|h\|hpp\|cc\)$' |
ack -x 'some thing'
이는 간단히 다음과 같이 해석됩니다. "c, cpp, h, hpp 또는 cc로 끝나는 모든 파일 이름을 검색합니다."
@nyxee의 아주 좋은 질문에 대해 내가 볼 수 있는 유일한 대답은 다른 파이프를 추가하는 것입니다.
locate --basename --regex '\.\(c\|cpp\|h\|hpp\|cc\)$' |
grep -v '/\.' |
ack -x 'some thing'
이렇게 하면 다음으로 시작하는 디렉터리나 하위 디렉터리를 건너뜁니다..
답변4
@chim님 답변이 제일 좋은데 댓글로 쓴거라 정식 답변으로 다시 올립니다...
ack -g '\bbar.*.c$' | ack -x foo
정규식 경로를 사용할 수 있다는 사실이 마음에 듭니다 ...