Python 파일에서 다음 두 줄의 코드를 sed
.
많은 명령을 시도했는데 sed
모두 일반 텍스트 줄에서 작동하지만 공백/탭 ^[ \s] 또는 ^[ \t]가 있는 줄에서는 작동하지 않습니다.
def get_user_creds(user):
# some lines of code
user.invoke()
user.process(user)
예상되는:
def get_user_creds(user):
# some lines of code
user.reinvoke()
답변1
re
로 모든 행을 삽입 user.invoke()
하고 모든 행을 삭제하는 것은 매우 쉬울 것이므로 user.process(user)
문제는 행이 함께 나타날 때만 변경하는 것입니다.
에서는 항상 두 줄을 함께 처리하고, 항상 추가 줄을 추가하고, 두 줄을 모두 채운 다음 첫 번째 줄을 인쇄하고 삭제하여 다음 줄을 계속 처리 sed
해야 할 때 이 패턴을 사용할 수 있습니다 .N;P;D
N
P
D
귀하의 경우:
sed '$!N;s/user.invoke().*\n.*user.process(user)/user.reinvoke()/;P;D'
(현재는 테스트할 수 없지만 작동할 것이라고 확신합니다.)
답변2
사용행복하다(이전 Perl_6)
~$ raku -e 'put slurp.subst(:global, / \h+ <( "user.invoke()" \n \h+ "user.process(user)" )> /, "user.reinvoke()" );' file
입력 예:
def get_user_creds(user):
# some lines of code
user.invoke()
user.process(user)
예제 출력:
def get_user_creds(user):
# some lines of code
user.reinvoke()
Raku는 Perl 계열의 프로그래밍 언어입니다. 위의 파일은 slurp
컴파일된 다음(즉, 한 번에 하나씩 메모리로 읽음) subst
인수(부사)를 사용하여 반복이 실행됩니다 :global
. 즉, 파일에서 일치하는 두 줄이 모두 대체됩니다.
매처는 적절한 공백( 가로 공백의 경우, 개행의 경우) / \h+ <( "user.invoke()" \n \h+ "user.process(user)" )> /
으로 둘러싸인 두 개의 리터럴 문자열(큰따옴표로 묶음)을 찾습니다 . 일치되면 ... 캡처 태그를 사용하여 교체할 콘텐츠를 설명합니다. 여기서 초기 값은\h
\n
<(
)>
\h+
포함되지표시를 캡처하여 새로 삽입된 문자열(예:" 들여쓰기 존중 ").
일반적으로 정규식을 이스케이프 처리하는 것은 고통스럽습니다. 그러나 Raku는 리터럴 문자열(위의 큰따옴표)을 허용하여 프로세스를 단순화합니다. 따옴표가 문제라면 백슬래시도 괜찮습니다. 문자를 문자 그대로 받아들이려면 [alnum 또는 underscore]가 아닌 모든 문자를 백슬래시하면 됩니다. 이는 백슬래시가 아닌 [숫자 또는 밑줄] 문자( "" dots 과 동일한 범주 .
)가 현재 특별한 의미가 할당되지 않은 경우에도 향후 특별한 의미를 갖지 않도록 유지합니다.
참고로 캡처/교체에 대해 매우 구체적으로 설명할 수 있습니다. 문자열 "user" 아래. 및 "invoke()"가 캡처되고 "re"가 대체 항목에 삽입되어 "reinvoke()"를 생성합니다.
~$ raku -e 'put S:g/ \h+ <( ("user.") ("invoke()") \n \h+ "user.process(user)" )> /$0re$1/ given slurp();' file
#OR
~$ raku -e 'put S:g[ \h+ <( ("user.") ("invoke()") \n \h+ "user.process(user)" )> ] = "$0re$1" given slurp();' file