찾기: 모든 수준에 존재하는 n개의 다른 디렉터리와 m개의 다른 파일을 제외하지만 일부 제외된 디렉터리에는 몇 개의 파일을 포함합니다.

찾기: 모든 수준에 존재하는 n개의 다른 디렉터리와 m개의 다른 파일을 제외하지만 일부 제외된 디렉터리에는 몇 개의 파일을 포함합니다.

경로 내의 모든 디렉터리와 파일을 재귀적으로 찾고 싶지만 특정 패턴과 일치하는 일부 다른 디렉터리와 파일을 제외하고 싶습니다. 그런 다음 검색 결과, 아마도 cp, mv또는 rsyncrm결과 에 대해 추가 명령을 수행하려고 합니다 find.

전체 및 디렉터리를 정리하고 디렉터리도 정리하고 싶지만 node_modules디렉터리 .git내의 알 수 없는 깊이에 존재하는 -name 을 가진 파일을 검색 결과에 포함하려고 한다고 build가정 해 보겠습니다 .enhancersxyz.jsenhancers

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-0grepxargscutsort

답변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 복사 이외의 작업을 수행하기 위해).

관련 정보