Script básico
Eu usei o perl porque é mais simples de combinar em várias linhas (diferente, digamos, do sed). O script básico é o seguinte.
perl -0777 -pe 's/^Log\.d\(.*?(\n.*?)*?\);\n//gm' input
Explicação
-
perl -0777 -pe: invoque o perl usando-0777para fazer o slurp do arquivo inteiro, ou seja, permitindo o processamento de várias linhas. -
's/foo/bar/gm': substituafooporbar, mesmo se houver várias correspondências (g); esta é uma expressão de múltiplas linhas (m). -
^Log\.d\(.*?(\n.*?)*?\);\n: procure por linhas que começam comLog.d(; essa expressão precisa ser escapada (^Log\.d\(). Pode haver mais caracteres após isso (.*?), possivelmente uma nova linha com mais caracteres ((\n.*?)) e, possivelmente, várias iterações dessa última expressão (*?). Depois disso, procure por um fechamento);seguido por uma nova linha (com escape de\);\n). Todos esses curingas são não-vorazes (*?não*). Assim, eles tentarão corresponder ao número mínimo de caracteres possíveis, em vez de excluir do primeiro^Log\.d\(ao final\);\ndo arquivo inteiro.
Teste
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
Executar script:
$ perl -0777 -pe 's/^Log\.d\(.*?(\n.*?)*?\);\n//gm' input.txt
Keep me A
Keep me B
Keep me C
Keep me D
Iterar vários arquivos
Após testar o script como acima, aplique-o em vários arquivos. Use a opção "no local" do perl ( -i ) para modificar os arquivos originais. Faça um backup do diretório primeiro. Se os arquivos estiverem todos diretamente no mesmo diretório, você pode simplesmente enviar vários argumentos para o script usando curingas do shell.
perl -i -0777 -pe 's/^Log\.d\(.*?(\n.*?)*?\);\n//gm' *.java
No entanto, dado que você pode ter diretórios aninhados (e eu não sei qual shell você está usando), você pode usar find aqui.
find /path/to/dir -name '*.java' -execdir perl -i -0777 -pe 's/^Log\.d\(.*?(\n.*?)*?\);\n//gm' {} \;
Explicação
-
find /path/to/dir: procure em/path/to/dir. -
-name '*.java': localize apenas arquivos correspondentes a essa expressão. -
-execdir perl -i -0777 -pe 's/^Log\.d\(.*?(\n.*?)*?\);\n//gm' {} \;: execute o script acima no local (-i) no arquivo correspondente{}.
Veja man find para mais informações sobre este formato.
benchmarking da versão sed
Como don_crissti sugere no comentários , há um comando sed que também fará isso.
sed -e '/Log/{' -e ': do' -e '/);/d;N' -e 'b do' -e '}' input.txt
Eu testei os dois comandos usando o seguinte arquivo como entrada.
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
Eu fiz alguns benchmarking comparando comandos. A versão perl é um pouco mais rápida para este arquivo no meu sistema.
$ 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
Eu também criei outro arquivo de teste com 1000 repetições do input.txt acima. Neste caso, a versão sed foi mais rápida.
$ 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