경로 내의 모든 디렉터리와 파일을 재귀적으로 찾고 싶지만 특정 패턴과 일치하는 일부 다른 디렉터리와 파일을 제외하고 싶습니다. 그런 다음 검색 결과, 아마도 cp
, mv
또는 rsync
의 rm
결과 에 대해 추가 명령을 수행하려고 합니다 find
.
전체 및 디렉터리를 정리하고 디렉터리도 정리하고 싶지만 node_modules
디렉터리 .git
내의 알 수 없는 깊이에 존재하는 -name 을 가진 파일을 검색 결과에 포함하려고 한다고 build
가정 해 보겠습니다 .enhancers
xyz.js
enhancers
xyz.js
아래 명령을 사용하여 검색 결과에 포함된 파일을 제외하고는 원하는 결과를 얻을 수 있었습니다 . 주문이 매우 깁니다.
find . -path "./node_modules" -prune -o -path "./.git*" -prune -o -path "./build" -prune -o -path "*/enhancers" -prune -o -print | grep 'xyz.js'
--root
|--node_modules
|--public
|--build
|--.git
|--.gitignore
|--.env
|--package.json
|--src
|--history
|--store
|--middleware
|..
|..
|--enhancers
|..
|--xyz.js
위의 개략적인 디렉터리 구조에서 는 |..
디렉터리 내부의 알 수 없는 깊이(수준)를 나타냅니다.
표시된 디렉터리 구조에서 다음을 제외한 모든 파일을 검색 결과에 포함하고 싶습니다.
- 전체
node_modules
디렉토리 - 전체
.git
디렉토리 .gitignore
문서- 전체
enhancers
디렉토리(xyz.js
검색 결과에 파일 포함)
이 작업을 수행하는 더 짧은 방법이 있습니까? 주요 혼란은 정규식과 전역 패턴 사이에서 발생합니다.
./.git*
교체를 사용 하면 ./\.git*
작동합니다.
*
여러 개를 사용하면 */enhancers
작동합니다.
find
파일 및 디렉터리 검색에 어떤 패턴 규칙이 명령에 적용됩니까?
답변1
그 안에 있는 파일을 찾을 수 있을 것으로 기대하더라도 enhancers
찾을 수 없습니다 prune
. 전혀 내림차순이 아니므로 거기에서 파일을 찾을 수 없다는 prune
의미 입니다. find
여기서는 이러한 파일을 자르지 않고 해당 파일 아래의 모든 파일을 제외합니다(이 xyz.js
파일 제외).
그래서:
find . \( \
-path ./node_modules -o \
-path './.git*' -o \
-path ./build \
\) -prune -o \( \
! -path '*/enhancers' ! -path '*/enhancers/*' -o \
-name xyz.js \
\) -print
가독성을 위해 다음은 몇 줄입니다.
이러한 파일로 작업을 수행하려면 -print
.-exec sh -c 'for file do something with "$file"; done' sh {} +
또는 출력을 사후 처리하려면 NUL로 구분된 입력을 처리할 수 있도록 // -print0
옵션 -z
(GNU 구현 또는 호환성 가정 )을 사용하십시오.--null
-0
grep
xargs
cut
sort
답변2
rsync
필터 규칙이 포함된 두 개의 명령줄을 사용하여 bash 쉘 스크립트를 만들 수 있습니다.
#!/bin/bash
rsync -Havn \
--filter="- target" \
--filter="- node_modules" \
--filter="- .git" \
--filter="- build" \
--filter="- enhancers" \
./ target
rsync -Havn \
--filter="+ xyz.js" \
--filter="+ */" \
--filter="- *" \
src target
좋은 출력을 생성할 때까지 이 셸 스크립트를 편집하는 것은 매우 쉽습니다. -n
즉, "모의 실행"에서는 해당 의도만 표시됩니다.
상황이 올바르다고 판단되면 -n
두 명령줄을 모두 제거하고 그대로 두어도 됩니다 rsync
. 아니면 텍스트 출력에 만족하여 파일에 저장하거나 다른 명령으로 파이프할 수도 있습니다(rsync 복사 이외의 작업을 수행하기 위해).