실제 예: Python 파일이 있고 함수 util.py
이름 중 하나를 . 함수 이름 으로 사용되는 다른 파일이 있을 수 있으며 이는 관련이 없습니다.foo
bar
foo
내 프로젝트의 모든 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
요구 됩니다.
- 재귀 검색(
-r
) - 일치하는 파일의 이름을 출력합니다(
-l
). -Z
LF( ) 대신 NUL로 구분- '.py'(
--include='*.py'
) 로 끝나는 파일만 고려하세요.
일치하는 모든 파일 (있는 경우 )에서 sed
내부 교체( )가 수행되어야 합니다 .-i
xargs -r
답변2
이것은 작동합니다.
/g
foo
모든 인스턴스를 대체합니다.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