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
로 대체됩니다( ). 이는 여러 줄 표현입니다( ).bar
g
m
^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