특정 디렉터리에서 특정 문자열이 포함된 파일을 찾아 교체합니다.

특정 디렉터리에서 특정 문자열이 포함된 파일을 찾아 교체합니다.

이런 폴더 구조가 있습니다.

.
└── apps/
    ├── bo/
    │   └── platform/
    │       └── values-dev.yaml
    ├── canary/
    │   └── platform/
    │       └── values-canary-dev.yaml
    ├── foo/
    │   ├── customer
    │   ├── audit
    │   ├── platform/
    │   │   └── values-foo-dev.yaml
    │   └── platform-gb/
    │       └── values-foo-dev.yaml
    └── bar/
        ├── customer
        ├── audit
        ├── platform/
        │   └── values-bar-dev.yaml
        ├── platform-usa/
        │   └── values-bar-dev.yaml
        ├── platform-ca/
        │   └── values-bar-dev.yaml
        └── platform-ie/
            └── values-bar-dev.yaml

표현에 대해 미리 죄송합니다.

다음을 사용하여 각 파일 에 있는 특정 문자열을 bash찾아 바꾸려고 합니다.puppyvalues-*-dev.yaml하지만foo각 하위 디렉터리 와 bar각 하위 디렉터리에 있는 파일을 변경 platform하고 다음 dog으로 바꾸고 싶습니다.dog

내가 얻은 가장 가까운 것은 다음과 같습니다. 여기에는 내부 파일만 나열되어 있지만 foo평생 동안 그것을 알아낼 수는 없습니다.

find . -type f -path '*foo/platform*' -name 'values-*-dev.yaml'

foo괄호로 묶어 추가하면 효과가 있을 줄 알았는데 bar그렇지 않네요.

find . -type f -path '*(foo|bar)/platform*' -name 'values-*-dev.yaml'

답변1

아니요, find' -name-path기본 sh 와일드카드 패턴만 지원되므로 ?범위/세트/클래스의 문자 수와 단일 문자(및 이스케이프)와 함께 작동하는 단일 문자만 지원됩니다.*[...]\

여기서는 표준을 사용하여 find다음을 수행합니다.

find . '(' -path '*/foo/platform*' -o -path '*/bar/platform*' ')' \
       -name 'values-*-dev.yaml' \
       -type f \
        -exec perl -pi -e 's/puppy/dog/g' {} +

일부 find구현에서는 -regex정규식을 사용하여 전체 경로와 일치하는 조건자를 지원합니다. ~을 위한확장하다regexps, BSD에서는 "옵션 조건자" 로 알려진 -Egrep/sed 및 GNU와 유사한 옵션을 사용할 수 있습니다 .find-regextype posix-extended

모든 변형에 대해 정규식은 암시적으로 고정되므로 다음이 필요합니다.

# BSD
find -E . -regex '.*/(foo|bar)/platform.*' \
          -name 'values-*-dev.yaml' \
          -type f \
          -exec perl -pi -e 's/puppy/dog/g' {} +
# GNU
find . -regextype posix-extended \
       -regex '.*/(foo|bar)/platform.*' \
       -name 'values-*-dev.yaml' \
       -type f \
       -exec perl -pi -e 's/puppy/dog/g' {} +

zsh또는 다음과 같이 사용할 수 있습니다 .

perl -pi -e 's/puppy/dog/g' -- **/(foo|bar)/platform*/**/values-*-dev.yaml(.)

zsh에는 다음을 포함하여 기본 sh를 기반으로 하는 몇 가지 유용한 glob 모드 확장이 있습니다.

  • **/모든 수준의 하위 디렉터리와 일치
  • (a|b): 확장 정규 표현식과 유사합니다.
  • 여기에 포함된 glob 한정자는 .검색을 다음으로 제한하는 데 사용됩니다.정기적인파일( finds 와 동일 -type f)

관련 정보