특정 확장자를 가진 파일이 폴더 구조에 존재하는지 확인하십시오(일부 디렉토리 제외).

특정 확장자를 가진 파일이 폴더 구조에 존재하는지 확인하십시오(일부 디렉토리 제외).

Typescript Mono-repo 프로젝트의 린터 역할을 할 CI 빌드에서 사용할 수 있는 스크립트를 구성하려고 합니다.

.js내가 달성하고 싶은 것은 프로젝트/패키지 저장소에 파일이 있는지 확인하는 것입니다 . 단, node_modules해당 파일이 있는 폴더와 common폴더 및 모든 하위 디렉터리와 파일은 피하는 것입니다.

파일 구조는 이렇습니다

project/
├── apps/
│   ├── app1
├── common/
│   ├── folder1
│   ├── folder1
│   ├── etc
├── lib/
│   ├── lib1
├── services/
│   ├── service1

services,lib,apps모든 npm 프로젝트의 하위 디렉터리입니다.

지금까지 시도한 다양한 시도 중 일부는 다음과 같습니다.

find . \( ! -name node_modules \) -o \( ! -path common -prune \) -name "*.js" -print

하지만 다른 화이트리스트 폴더에 더미 파일을 생성하더라도 .js아무 것도 반환하지 않는 것 같습니다./project

이 시도는 테스트 파일을 인쇄하기 때문에 가장 가까운 것으로 보이지만 에서 파일도 찾았 common지만 블랙리스트에 추가해야 합니다.

find . -type d \( -path common -o -name node_modules \) -prune -false -o -name '*.js'

이 실행의 출력:

./test.js
./common/temp/pnpmfile.js
./common/temp/pnpm-store/2/registry.npmjs.org/ipaddr.js
./common/config/rush/pnpmfile.js
./common/scripts/install-run.js
./common/scripts/install-run-rushx.js
./common/scripts/install-run-rush.js
./services/test.js

이 스크립트에서 내가 원하는 전반적인 목표는 파일이 화이트리스트 디렉터리에 없으면 0을 종료하고 .js파일이 블랙리스트 디렉터리 외부에 있으면 1을 종료하는 것입니다..js

저는 초보자이고 쉘 명령에 대한 경험이 없으므로 도움을 주시면 대단히 감사하겠습니다. 미리 감사드립니다!

답변1

귀하의 주문은 거의 정확합니다. 수정하세요:

find . \( -name node_modules -o -path ./common \) -prune -o -name '*.js' -print

이렇게 하면 이름이 지정 node_modules되거나 에 있는 모든 항목이 잘립니다 ./common. 사용되는 경로 이름은 -path최상위 검색 경로로 시작하는 이름이므로 .이 경우에는 로 시작해야 합니다.

당신이 -false사용하는 것은 필수가 아닙니다. node_modules이후 테스트 와 ./common일치하는 경우 필수입니다. 이 경우에도 사용하고 싶을 수도 있지만 지금은 그럴 필요가 없습니다.-name-o-type d

시험:

$ tree
.
|-- common
|   `-- file.js
|-- dir
|   |-- common
|   |   `-- file.js
|   |-- file.js
|   `-- node_modules
|       `-- file.js
`-- node_modules
    `-- file.js

5 directories, 5 files
$ find . \( -name node_modules -o -path ./common \) -prune -o -name '*.js' -print
./dir/file.js
./dir/common/file.js

파일이 ./dir/common/file.js정리되지 않은 디렉터리에 있기 때문에 발견되었습니다( common현재 디렉터리 바로 아래에 있는 경우에만 정리됩니다).


다른 곳에서, 당신은 단지 그것이 있는지 확인하고 싶은 것 같습니다어느*.js디렉터리에서 일치하는 파일은 정리되지 않습니다. 다음과 같이 하면 효과적으로 이 작업을 수행할 수 있습니다.

if find . \( -name node_modules -o -path ./common \) -prune -o -name '*.js' -exec echo . \; | grep -q .
then
    echo there are JS files
else
    echo there are no JS files
fi

여기에서는 파일을 찾을 때마다 점(어떤 문자든 가능)을 출력하고 이를 grep -q .감지 에 사용합니다 find. 무언가가 발견되면 grep"성공"을 의미하는 0 종료 상태로 종료되고 명령문은 if첫 번째 항목을 사용합니다. 나뭇가지. 명령은 더 이상 수신하지 않는 파이프에 다른 지점을 쓰려고 find시도하자마자 종료됩니다.grep

답변2

-path 를 사용하는 경우 발견된 트리의 어느 위치와 일치하는지 ./common와 같이 완전히 선언된 경로를 사용하십시오 .-name

이 명령은 나에게 시험이다.

find . -type d \( -name common -o -name node_modules \) -prune -false -o -name '*.js'

답변3

위의 답변 중 일부를 보고 테스트한 후 최종적으로 사용한 명령은 다음과 같습니다.

find . \( -name node_modules -o -path ./common \) -prune -o -name '*.js' -print

인수를 유지해야 했던 이유 -print는 이를 실행할 때 얻은 출력이 -print일부 폴더를 다음과 같은 출력으로 표시하지 않는다는 것을 발견했기 때문입니다.

./common
./lib/trader-sdk/node_modules
./lib/is-ticker-symbol/node_modules
./apps/cron-app/node_modules
./services/templating-service/node_modules
./services/api-service/node_modules
./services/trading-services/node_modules
./services/sentiment-service/node_modules

하지만 arg를 추가하면 -print출력이 아무것도 되지 않습니다. 이는 이 경우 예상되는 결과입니다.

.js보너스: 마지막 사용 사례는 다음과 같습니다. TypeScript 모노 저장소를 검사하여 빌드 파일을 마스터에 병합 하려는 사람이 없는지 확인하는 기본 스크립트입니다 .

#!/bin/bash

jsFiles=$(find . \( -name node_modules -o -path ./common \) -prune -o -name '*.js' -print)

if [ -z "$jsFiles" ]
then
      echo "No JS files found, free to proceed"
      exit 0
else
      echo "JS files found, unable to proceed"
      exit 1
fi

관련 정보