我有一个 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
基本脚本
我使用 perl 是因为它更容易匹配多行(不像 sed)。基本脚本如下。
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
迭代多个文件
按上述方式测试脚本后,将其应用到多个文件。使用perl 的“就地”选项( -i
) 修改原始文件。首先对目录进行备份。如果文件都直接位于同一目录中,则可以使用 shell 通配符向脚本发送多个参数。
perl -i -0777 -pe 's/^Log\.d\(.*?(\n.*?)*?\);\n//gm' *.java
但是,考虑到您可能有嵌套目录(并且我不知道您正在使用哪个 shell),您可以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
:在匹配文件上就地()运行上面的脚本{}
。
查看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
我还创建了另一个测试文件,该文件重复了 1000 次input.txt
上述内容。在这种情况下,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