有一种需求,叫做对jar包反编译出源码方便查看。
Java Decompiler是个非常不错的工具
ubantu系统下载deb包,使用 dpkg -i 包名 进行安装。安装完成后在/opt/jd-gui文件夹就是安装好之后的目录。
jd-tui文件夹下有个文件jd-gui.desktop文件,拷贝到桌面之后,双击,信任,之后可以打开界面。
添加jar包之后就可以反编译出.java格式的java源码,还可以将源码另存到一个zip文件中,解压之后就有对应的包名和对应的java文件。
但是,某一个java文件可能是下图这样的:
更有甚者,会有很多类似空行
每个反编译出来的java源文件末尾还有类似签名
所以现在的目标是讲/* */ 去除。"*" 和 "/" 都需要前面使用反斜杠"\"进行转义。在空格的前面不需要进行转义。
使用sed -i命令可以解决这个问题。
如果在vim中进行替换:,则只可以一次操作一个文件。使用sed命令的优势是可以一次操作多个文件。
sed -i 命令的格式是: sed -i 's/old_str/new_str/g'。/g的作用是全局替换。
现在插入一个小插曲,正则表达式和通配符的区别是什么?什么是正则表达式?什么是通配符?
正则表达式和通配符的区别:
什么是正则表达式?
什么是通配符?
有了上面的基础,所以使用正则表达式来完成我们的操作。
sed -i 's/\/\* \*\/ //g' DigestChallenge.java
上面的语句对起作用,但是如果出现
这种情况,怎么办?
也就是说,两个星号*内部夹着5个字符,这些字符可能是空格" ",也可能是数字"1"。解决:可以使用正则表达式元字符"."匹配除了换行符之外的任意字符。
sed -i 's/\/\*.....\*\///g' DigestChallenge.java
完成,但是替换之后的结果会出现多个空行:
而且,有的还是没有去除(因为中间有4个空格,而不是5个)
使用下面一行的命令可以完成,.匹配任意字符,*代表重复的次数。最后面的*是一个通配符,匹配所有文件。
adog@E531:client$ sed -i 's/\/.*\*\///g' *
但是问题来了,我有很多个文件夹,每个文件夹内部可能还有很多文件夹后者文件,那么如何找出所有文件夹中的所有文件,并对这些文件进行sed -i操作进行替换呢?
这里再次引入一个小插曲,即grep命令的使用
查看grep命令的帮助文档:
-l, --files-with-matches
Suppress normal output; instead print the name of
each input file from which output would normally
have been printed. The scanning will stop on the
first match.
-r, --recursive
Read all files under each directory, recursively,
following symbolic links only if they are on the
command line. Note that if no file operand is
given, grep searches the working directory. This is
equivalent to the -d recurse option.
Repetition
A regular expression may be followed by one of several
repetition operators:
? The preceding item is optional and matched at most
once.
* The preceding item will be matched zero or more
times.
+ The preceding item will be matched one or more
times.
{n} The preceding item is matched exactly n times.
{n,} The preceding item is matched n or more times.
{,m} The preceding item is matched at most m times. This
is a GNU extension.
{n,m} The preceding item is matched at least n times, but
not more than m times.
-r参数的作用是递归进行查询,-l参数的作用是第一次匹配到之后就停止。
-l参数解释:如果文件a.txt中有多个相通的字符串abc.....abc.....abc,如果不加-l参数,则会匹配三次,每次匹配到都输出一次
如果不加-l,如下,,点"."表示当前目录
字符串public在文件DigestChallenge.java文件中出现了多次,每次匹配到都打印出来,所以,这不是我们想要的,所以需要加上-l参数。
也就是说,递归查找所有的文件。
现在文件路径和文件名都有了,接下来就是讲sed命令和grep命令结合在一起了。
直接上命令:
sed -i 's/\/.*\*\///g' `grep "*" -rl .`
其中,grep命令相关被符号``包围了。这样就能实现递归对指定的所有文件夹的所有文件进行sed替换操作了。
只剩下删除空行的操作了:
上面的命令只能删除纯正的空行,即不含有任何的空格或者Tab符号。
下面的命令能够删除所有空行,包括非纯正空行(包含空格或者Tab符)和纯正空行(不包含空格或者Tab符,即直接回车后的空行)。
综上,两条命令达到目标:
替换的话前有s,删除的话后有d
-----------完--------------