find에서 grep까지의 파이프라인

find에서 grep까지의 파이프라인

나는 무엇을 하고 싶은가?

프로젝트의 다른 파일에 필요하지 않은 파일을 찾는 명령을 작성합니다.

나는 무엇을 시도했는가?

나는 find파일 이름 목록을 얻는 데 사용합니다. 이제 검색할 파일 대신 파일 이름을 검색 문자열로 사용하고 싶습니다.

나는 find server/lib -type f -exec basename {} \; | cut -f 1 -d '.'파일 이름 목록을 얻고 파일 확장자를 제거하는 데 사용합니다.

이제 이것이 각 파일 이름을 파이프로 연결하려는 대상이라는 것을 알았지 grep -R --exclude-dir=node_modules <search-string> . -l만 이를 매개변수로 전달하는 방법을 모르겠습니다 <search-string>.


기타 정보

grep나는 또한 파이핑이 전체 결과(전체 파일 목록)를 전달할 수 있다는 것을 막연하게 알고 있는데 find, 나는 분명히 그렇게 하고 싶지 않습니다. 따라서 그것이 내가 할 일이라면 말해 주세요.

또한 (이것은 아마도 이 질문의 범위를 벗어나더라도) grep아무것도 발견되지 않은 파일 이름을 찾는 방법으로 이것을 사용하고 있기 때문에 그러한 출력을 얻는 것에 대한 제안은 크게 감사하겠습니다.

> <the-command>

filename1
server/lib/foo.js # where these are the list of files in which it appears
test/lib/foo.js

filename2
Not Found! #where `filename2` wasn't found anywhere (obviously)

답변1

그리고 zsh:

projects=(server/lib/**/*(D.:t:r))
grep -rFl --exclude-dir=node_modules -e${(u)^projects} .
  • **/재귀적 와일드카드. zsh1990년대 초반에 도입된 기능입니다.
  • (D.:t:r)zsh이름 이외의 속성을 사용하여 파일을 선택하거나 발견된 파일의 정렬 또는 수정을 변경할 수 있는 특정 기능인 전역 한정자입니다 .
  • D: 도트 파일을 포함하고 도트 디렉터리를 있는 그대로 트래버스합니다 find. 아마도 당신은 그 것을 벗고 싶을 것입니다.
  • .:일반 파일만( -type ffind:)
  • :t, :r: 기록 수정자는 csh/와 유사 bash하지만 여기서는 와일드카드 파일에 적용됩니다. :t꼬리(기본 이름)이고 :r루트 이름(확장자 제거됨)입니다.
  • x${^array}rc's x^$array또는 fish's 와 같은 x$array요소를 배포합니다 . 예를 들어 $array( 1, 2)인 경우입니다. 그것은 가 된다 x1 x2.
  • ${(u)array}( unique의 경우) 중복을 제거합니다( (u)매개변수 확장 플래그로).

포함된 파일 목록의 경우전혀문자열 -l로 대체됩니다 -L(GNU 가정 grep하지만 여기에서는 이미 GNU 특정 옵션을 사용하고 있습니다). -F고정 문자열 검색에 사용됩니다(이러한 프로젝트 이름이 정규식으로 처리되는 것을 원하지 않기 때문입니다). 다음에 대한 -w옵션을 추가할 수도 있습니다 .grep단어foo일치하지 않음 foobar(그러나 여전히 일치함 ) 과 같은 일치입니다 foo-bar.

답변2

짧은 답변:

이것은 단지 여러 줄을 다른 명령에 대한 인수로 전달하려는 경우에 xargs적합합니다 . 이 경우 명령 중간에 넣기 때문에 해당 -I {}플래그를 사용하는 것이 좋습니다. 이것은 {}어디든 놓을 수 있도록 자리 표시자로 설정되어 있습니다(직접 자리 표시자를 설정할 수 있지만 {}다른 많은 항목과 혼동되지 않기 때문에 저는 일반적으로 이것을 고수합니다.

모든 것을 종합해 보면(당신이 제공한 명령이 당신이 생각하는 대로 작동한다고 가정합니다!):

find server/lib -type f -exec basename {} \; | cut -f 1 -d '.' | xargs -I {} grep -R --exclude-dir=node_modules {} . -l

긴 대답

좋아요, 어쩌면 한 단계 더 나아갈 수 있을 것 같아요. 앞서 언급한 형식을 원한다고 가정하면 xargs다음 sh -c과 같이 명령을 연결할 수 있습니다.

find server/lib -type f -exec basename {} \; | cut -f 1 -d '.' | xargs -I {} sh -c "echo {}; grep -R --exclude-dir=node_modules {} . -l"

내 컴퓨터에서 이것을 실행하면 파일이 있는 파일을 제공하는 것처럼 보입니다.확립된. 내 두뇌는 피곤하므로 예쁜 스크립트로 마무리하지 마세요(한 줄짜리 스크립트가 거칠어지기 시작할 때 실제로 해야 합니다.https://www.shellcheck.net/그 동안) 이 끔찍한 해킹을 대신 사용할 수 있습니다. 그러면 (제 생각에는) 원하는 결과를 얻을 수 있을 것입니다.

find server/lib -type f -exec basename {} \; | cut -f 1 -d '.' | xargs -I {} sh -c "echo {}; grep -R --exclude-dir=node_modules {} . -l && printf \"\n\" || printf \"Not found\n\n\""

관련 정보