기본 스크립트

기본 스크립트

Android 앱이 있고 Log.d(.....);삭제하고 싶은 유형의 메시지가 많이 있습니다.

나는 그것들을 모두 삭제하는 명령을 원합니다 (모든 디렉토리를 재귀 적으로 통과해야 함)

그러나 한 가지 문제는 일부 Log.d명령이 다음 줄로 이동하므로 일부 명령은 다음과 같다는 것입니다.

Log.d("I can be easily deleted", "");

다른 사람들도 다 그렇지

Log.d("I span a new line, "hel" 
+ "lo");

또한 간격이 모두 동일할 필요는 없습니다. 하나는 Log.d줄 시작 부분부터 30자, 다른 하나는 14자 등이 될 수 있습니다.

Log.d나는 그들이 모두 로 시작 하고 로 끝나는 것이 도움이 될 것이라고 생각했습니다.);

이는 모든 .java 파일(*.java)에서만 실행되어야 합니다.

이를 수행하는 명령은 무엇입니까? 감사해요

답변1

기본 스크립트

(sed와 달리) 여러 줄을 일치시키는 것이 더 쉽기 때문에 Perl을 사용합니다. 기본 스크립트는 다음과 같습니다.

perl -0777 -pe 's/^Log\.d\(.*?(\n.*?)*?\);\n//gm' input

설명하다

  • perl -0777 -pe: Perl을 호출하여 -0777전체 파일을 읽고 여러 줄 처리를 허용합니다.
  • 's/foo/bar/gm': 일치하는 항목이 여러 개인 경우에도 foo로 대체됩니다( ). 이는 여러 줄 표현입니다( ).bargm
  • ^Log\.d\(.*?(\n.*?)*?\);\n: ;로 시작하는 줄을 찾습니다 Log.d(. 표현식을 이스케이프해야 합니다( ^Log\.d\(). 이 뒤에 더 많은 문자가 있을 수 있고( ) .*?더 많은 문자를 포함하는 개행 문자가 있을 수 있으며( ) (\n.*?)마지막 표현식 *?이 여러 번 반복 될 수 있습니다( ). 그런 다음 종결자 );뒤에 개행 문자(로 이스케이프됨 )가 오는 것을 찾으십시오 \);\n. 이러한 와일드카드는 모두 욕심이 없습니다( *?not *). 따라서 ^Log\.d\(전체 파일의 처음부터 마지막까지 삭제하는 대신 가능한 가장 작은 문자 수를 일치시키려고 합니다 .\);\n

시험

input.txt:

Keep me A
Log.d("I can be easily deleted", "");
Keep me B
Keep me C
Log.d("I span a new line, "hel" 
+ "lo");
Keep me D

스크립트를 실행합니다:

$ perl -0777 -pe 's/^Log\.d\(.*?(\n.*?)*?\);\n//gm' input.txt
Keep me A
Keep me B
Keep me C
Keep me D

여러 파일을 반복

위와 같이 스크립트를 테스트한 후 여러 파일에 적용해 보세요. -i원본 파일을 수정하려면 Perl의 "in-place" 옵션( )을 사용하십시오 .먼저 디렉토리를 백업하십시오.파일이 모두 동일한 디렉토리에 직접 있는 경우 쉘 와일드카드를 사용하여 여러 매개변수를 스크립트에 보낼 수 있습니다.

perl -i -0777 -pe 's/^Log\.d\(.*?(\n.*?)*?\);\n//gm' *.java

그러나 아마도 중첩된 디렉토리가 있다는 점을 고려하면(그리고 어떤 쉘을 사용하고 있는지는 모르겠습니다) find여기에서 사용할 수 있습니다.

find /path/to/dir -name '*.java' -execdir perl -i -0777 -pe 's/^Log\.d\(.*?(\n.*?)*?\);\n//gm' {} \;

설명하다

  • find /path/to/dir: 보세요 /path/to/dir.
  • -name '*.java': 이 표현식과 일치하는 파일만 찾습니다.
  • -execdir perl -i -0777 -pe 's/^Log\.d\(.*?(\n.*?)*?\);\n//gm' {} \;-i:일치하는 파일에서 위 스크립트 in-place()를 실행합니다 {}.

man find이 형식에 대한 자세한 내용을 확인하세요 .

sed 버전 벤치마크

~처럼돈 크리스티다음을 권장합니다.논평, 이 작업도 수행할 수 있는 sed 명령이 있습니다.

sed -e '/Log/{' -e ': do' -e '/);/d;N' -e 'b do' -e '}' input.txt

다음 파일을 입력으로 사용하여 두 명령을 모두 테스트했습니다.

Keep me A
Log.d("I can be easily deleted", "");
Keep me B
Keep me C
Log.d("I span a new line, "hel" 
+ "lo");
Keep me D
Log.d("I span a new line, "hel" 
+ "lo" +
+ "there");
Keep me E

명령을 비교하는 몇 가지 벤치마크를 수행했습니다. 내 시스템에서는 perl이 파일의 버전이 약간 더 빠릅니다.

$ time (for i in {1..1000}; do perl -0777 -pe 's/^Log\.d\(.*?(\n.*?)*?\);\n//gm' input.txt > /dev/null; done)

================
CPU 101%
user    1.484
system  3.372
total   4.793
$ time (for i in {1..1000}; do sed -e '/Log/{' -e ': do' -e '/);/d;N' -e 'b do' -e '}' input.txt > /dev/null; done)

================
CPU 101%
user    2.647
system  2.847
total   5.429

input.txt위의 내용을 1000번 반복하는 또 다른 테스트 파일도 만들었습니다 . 이 경우 sed 버전이 더 빠릅니다.

$ time (for i in {1..100}; do perl -0777 -pe 's/^Log\.d\(.*?(\n.*?)*?\);\n//gm' input1000 > /dev/null; done)

================
CPU 100%
user    1.132
system  0.409
total   1.535
$ time (for i in {1..100}; do sed -e '/Log/{' -e ': do' -e '/);/d;N' -e 'b do' -e '}' input1000 > /dev/null; done)

================
CPU 100%
user    0.560
system  0.298
total   0.853

관련 정보