서로 다른 줄에 두 개의 문자열이 포함된 파일을 찾는 방법

서로 다른 줄에 두 개의 문자열이 포함된 파일을 찾는 방법

실제 예: Python 파일이 있고 함수 util.py이름 중 하나를 . 함수 이름 으로 사용되는 다른 파일이 있을 수 있으며 이는 관련이 없습니다.foobarfoo

내 프로젝트의 모든 Python 파일을 에서 으로 업데이트하고 싶습니다 . 따라서 foo다음 bar과 같은 가져온 파일을 검색하고 싶습니다.

import project.path.util

또는

from project.path.util import foo

다음으로 시작하는 모든 foo통화:

foo(

솔루션은 공백을 허용할 수 있어야 합니다. 각각을 사용하여 검색할 수 있지만 grep검색을 결합하는 것에 대해서는 잘 모르겠습니다. 어떤 조언이라도 대단히 감사하겠습니다.

답변1

GNU 도구 사용:

grep -rlZ --include='*.py' -e 'import project.path.util' \
                           -e 'from project.path.util import.*\bfoo\b' . |
  xargs -r0 sed -i 's/\bfoo\b/bar/g'

이는 다음에서 grep요구 됩니다.

  1. 재귀 검색( -r)
  2. 일치하는 파일의 이름을 출력합니다( -l).
  3. -ZLF( ) 대신 NUL로 구분
  4. '.py'( --include='*.py') 로 끝나는 파일만 고려하세요.

일치하는 모든 파일 (있는 경우 )에서 sed내부 교체( )가 수행되어야 합니다 .-ixargs -r

답변2

이것은 작동합니다.

/gfoo모든 인스턴스를 대체합니다.bar

find <Project root dir> -type f -exec sed -i "{}" -e 's/foo/bar/g' \;

*.py 파일만 변경하도록 제한하려면 다음을 수행하세요.

find <Project root dir> -type f -name "*.py" -exec sed -i "{}" -e 's/foo/bar/g' \;

교체해서는 안 되는 foo 인스턴스가 있는 경우 4가지 경우로 제한할 수 있습니다.

  • 수입부자
  • 모듈에서 가져오기부자
  • 정의부자
  • 부자(

하지만

  • 젠장_푸(
  • 빌어먹을 부자(
  • 젠장 1foo(
  • 빌어먹을 부자 (

그러면 명령은 다음과 같습니다.

foo="foo";bar="bar";find <Project root dir>  -type f -exec sed -i "{}" \
-r -e "s/[^a-zA-Z0-9_\-]$foo\(/$bar\(/g" -e "s/def $foo/def $bar/g" \
-e "s/import $foo/import $bar/g" \;

답변3

검색하려는 디렉터리에 있다고 가정합니다(모든 하위 디렉터리와도 일치함).

 for i in `find . -type f -name '*.py' -exec grep -lr 'foo' {} +`; do sed -i 's/foo/bar/' $i; done

편집하다:

"damned_fools"와 같은 문자가 포함된 함수 일치를 방지하려면 \b를 사용하여 단어 경계를 일치하도록 개선할 수 있습니다.

for i in `find . -type f -name '*.py' -exec grep -lr 'foo' {} +`; do sed -i 's/\bfoo\b/bar/' $i; done

인용하다: https://stackoverflow.com/questions/1032023/sed-whole-word-search-and-replace

관련 정보