不知道什么是Perl猛戳这个链接 http://zh.wikipedia.org/wiki/Perl



   
任务:    

           
随着手机/平板的各方面性能的不断发展(CPU,内存,存储),Android这个移动领域绝对的霸主也升级到了4.1版本,软硬件的提高意味着人们对使用体验有了越来越高的要求,在移动设备里面安装的App也越来越多,但是Android总是以刷机为乐趣的,每次刷机就意味着要备份软件(这里不讨论软件数据的备份),也就意味着备份apk,apk一多,管理起来就成了一件头痛的事情,最起码的,我们要知道我们都备份了哪些apk,最最起码要知道它们叫什么名字,因为不管在windows还是linux平台下面,都是无法直接解析apk的名字的。所以不管你是以什么样的方式备份出来的apk,它总不可能是按你的要求来命名的,今天的目标/任务就是把apk按你的要求来命名。

方法:

           
由于在windows/linux上无法直接通过系统的文件管理器解析apk的名字等等属性,所以必须要借助别的工具,这其中最好的必须是Google自家的aapt工具,不知道aapt是什么?猛戳这个链接http://www.ltesting.net/ceshi/ceshijishu/sjcs/android/2012/0511/204843.html。aapt可以直接读取出来一个apk的各种属性,比如AndroidManifest.xml里面定义的包名,软件名,版本号,使用的权限等等信息。使用aapt读取出来的信息是一大堆,所以必须要使用正则表达式的模式匹配获取我们所需要的信息,然后再根据要求来给相应的apk重命名。注意,这个地方是要给当前目录下所有的apk自动重命名,所以,必然要用到for语句(在perl里面是foreach)。

先介绍一下aapt的使用。这里只介绍用到的功能,dump,具体命令是aapt d(ump) badging
mms.apk。它会打印出如下的信息:



package: name='com.elsdoerfer.android.autostarts' versionCode='24'
versionName='1.7.7'

sdkVersion:'4'

targetSdkVersion:'14'

application-label:'Autostarts'

application-label-zh:'自启管家'

application-icon-160:'res/drawable/icon.png'

application-icon-240:'res/drawable-hdpi/icon.png'

application: label='Autostarts' icon='res/drawable/icon.png'

launchable-activity:
name='com.elsdoerfer.android.autostarts.ListActivity' 
label='Autostarts' icon=''

uses-permission:'android.permission.WRITE_SETTINGS'

uses-permission:'android.permission.WRITE_SECURE_SETTINGS'

uses-permission:'android.permission.CHANGE_COMPONENT_ENABLED_STATE'

uses-configuration:

uses-gl-es:'0xffffffff'

uses-feature:'android.hardware.touchscreen'

uses-implied-feature:'android.hardware.touchscreen','assumed you
require a touch screen unless explicitly made optional'

main

other-activities

supports-screens: 'small' 'normal' 'large' 'xlarge'

supports-any-density: 'true'

locales: '--_--' 'zh'

densities: '160' '240'



   
注意,在windows的cmd里面,编码是cp936,和aapt默认输出的utf8是冲突的,所以如果你直接执行上述命令,会在cmd的窗口中看到所有的中文都是乱码的,正确的方法是把输出的结果重定向到文本文件里面,再用记事本或其它的工具打开输出的文本文件,就不会有乱码了。关于aapt的其它用法请自行查看帮助,直接输入aapt即可。

我们的目标就是要从上面的那一堆的数据中,用perl里面的正则表达式提取出我们需要的信息,我所需要的信息数据于这样:Google
Play
音乐_v5.0.1053J.731804_(com.google.android.music).apk,软件名称_v版本号_(apk的包名).apk。

通过分析上面的输出结果可以看到:

       
name='com.elsdoerfer.android.autostarts'

       
versionName='1.7.7'

       
application-label:'Autostarts'

       
application-label-zh:'自启管家'

   
这四个字符串是我们要需要的,下面的任务就是如何把它们的值提取出来。下面上整个程序的perl源代码。





# use strict;

use Encode;

use open ':encoding(GBK)', ':std';

use open ':encoding(UTF-8)';



my @files = (glob(".*.apk"), glob("*.apk"));



foreach (@files)

{

    # print
"Start Processing -> $_ \n";



    #
执行aapt并赋值给$info

    $info =
`aapt d badging $_`;



    $info =~
m/name=\'(.*?)\'/;

    $pkg_name =
$1;  # apk的包名

    $info =~
m/versionName=\'(.*?)\'/;

    $version =
$1;  # apk的版本号



    # 判断是否存在
label-zh_CN名字,

    #
若不存在则以label名字代替

    if ($info =~
m/application-label-zh_CN:\'(.*?)\'/) {

  
   
 $name = $1;

    }

    else {

  
   
 $info =~ m/application-label:\'(.*?)\'/;

  
   
 $name = $1;  

    }



    #
拼接格式化后想要的文件名

  
 $out_filename =
"$name\_v$version\_($pkg_name).apk";



    open(LOG,
">>log.txt") || warn "Can't Open the file";

    print LOG
"$out_filename \n";



    #
必须要转换成gb2312编码,否则会造成中文乱码

  
 $out_filename = encode("gb2312",
$out_filename);

    print
decode("gb2312", $out_filename);



    #
若修改后导致文件重名,则输出警告,不作处理

    if(-e
$out_filename){

  
   
 warn "Can't rename $_ to $out_filename.

  
   
 The $out_filename exists!\n";

    }

    else{
 

  
   
 # 重命名文件,若重命名失败,则输出警告

  
   
 # 注意此处不要调用system("ren $a $b")或`ren a b`

  
   
 # 因为直接调用会造成文件名有空格会重命名失败的问题

  
   
 rename $_, $out_filename

  
   
   
 or warn "Rename $_ to $out_filename failed:
$!\n";



    }



    print
"\n";

}



close LOG || warn "Can't close the file";







   
对这个perl文件作一个小小的解释:

       
my @files = (glob(".*.apk"),
glob("*.apk"));   
使用glob()函数获取到目录下面的所有文件名,这里使用的是*.apk和.*.apk,这两个是有区别的,因为perl源于unix/linux,在linux下面,所有以点开头的文件都是隐藏文件,程序默认是不解析的,所以我们必须要加上.*.apk。

foreach
(@files)   
{  }  
perl里面的for循环是用foreach来实现的,对于@files这个数组里面的所有元素,它会依次执行大括号里面的语句。

       
$info =~ m/name=\'(.*?)\'/; 
正则表达式,=~m表示模式匹配,/.../之间的内容是正则表达式的主体,name=\'(.*?)\'表示取name='...'单引号里面的内容,就是我们所需要的。具体正则表达式的语法,请自行google。

$out_filename = encode("gb2312",
$out_filename);   由于
perl起码起源于linux/unix,故其内部处理数据都是以utf8编码来实现的,而windows的cmd是cp936,如果不做编码转换的话,直接调用perl的rename对文件重命名的时候就会出现中文乱码的情况,所以这里用encode()函数把所需要的目标文件名转换成gb2312编码,即cp936。

执行perl
rename_apk.pl,它会自动查找当前目录下的所有apk,并按给定的 软件名称_v版本号_(apk的包名).apk
这个规则重命名,同时会在当前目录下输出一个log.txt文件,它会记录所有已经格式化好的目标文件名,一来是可以查看目标文件名有没有正确,二来是可以给那些因为有特殊字符而不能自动重命名的apk一个供修改的文件名,方便手动修改文件名然后再手动重命名。

好了,以上这个perl文件就是我花了一天时间从零开始学习perl和正则表达式所写出来的东西,达到了我所要的目标,现总结一下对perl印象深刻的几个地方:

1. 它的变量不分类型,什么整数啊,浮点数啊,字符串啊,都是直接用$var来定义的。

       
2.
`...`,可以使用这条语句执行原本可以在cmd里面执行的命令,即直接调用外部shell的命令,当然,也可以用system()来调用,作用貌似是一样的。

3. 数组使用@var来定义,可以直接用foreach(@var)来遍历。

       
4.
在foreach中,直接使用$_这个变量来调用数组中存在的当前正在使用的元素的值。比如数据中存的是5个字符串,foreach就是依次遍历5次,然后每次使用$_就是直接调用当前个元素的值。

5. 在print里面,可以直接把变量替换成对应的值输出。比如$a = "abc",  print
"123$a"输出的结果就是123abc,需要注意的是此处的print后面是用的双引号,如果是用单引号,则不解析变量的值,这里有点类似于PHP的语法。

OK,学习笔记记录完毕,凌晨12点40分,准备睡觉。

初尝Perl -- 使用aapt给apk软件包批量重命名的更多相关文章

  1. 初尝 Perl

    本文将阐述以下几方面内容: 1.什么是Perl 2.Perl有什么用 3.Windows 下的Perl环境搭建 4.Perl 版Hello World 5.Perl 语法梗概 6.一些参考资料 什么是 ...

  2. 初尝Windows 下批处理编程

    本文叫“ 初尝Windows 下批处理编程”是为了延续上一篇“初尝 Perl”,其实对于博主而言批处理以及批处理编程早就接触过了. 本文包括以下内容 1.什么是批处理 2.常用批处理命令 3.简介批处 ...

  3. seajs初尝 加载jquery返回null解决学习日志含示例下载

    原文地址:http://www.tuicool.com/articles/bmuaEb 如需demo示例,请点击下方链接下载: http://yunpan.cn/cVEybKs8nV7CF  提取码 ...

  4. .NET领域驱动设计—初尝(三:穿过迷雾走向光明)

    开篇介绍 在开始这篇富有某种奇妙感觉的文章之旅时我们先短暂的讨论一下关于软件开发方法论的简要: 纵观软件开发方法论,从瀑布模型.螺旋模型.RUP(统一软件开发过程).XP(极限编程).Agile(敏捷 ...

  5. 初尝微信小程序2-Swiper组件、导航栏标题配置

    swiper 滑块视图容器. 很多网页的首页都会有一个滚动的图片模块,比如天猫超市首页,滚动着很多优惠活动的图片,用来介绍优惠内容,以及供用户点击快速跳转到相应页面. Swiper不仅可以滚动图片,也 ...

  6. Android CTS - Cannot run program "aapt"/ Fail to run aapt on .../apk installed but AaptParser failed

    今天同事碰到cts的一些问题,跑到某个apk的时候,就提示如下错误: Cannot run program "aapt": error=2. No such file or dir ...

  7. 分布式设计《初尝memcached》

          之前听说过高性能的分布式缓存开源工具,但一直没有真正接触过,如今接触的产品中实用到过分布式缓存.所以决定一探到底.memcached是一个优秀的开源的分布式缓存工具.也是眼下比較火热的分布 ...

  8. Android自动化测试探索(三)Android SDK tools安装、aapt配置以及使用aapt获取apk包名

    Android SDK tools安装 下载连接: https://www.androiddevtools.cn 找到对应mac的版本下载安装即可 AAPT配置 #1. 进入根目录 cd ~ #2. ...

  9. .NET领域驱动设计—初尝(一:疑问、模式、原则、工具、过程、框架、实践)

     .NET领域驱动设计—初尝(一:疑问.模式.原则.工具.过程.框架.实践) 2013-04-07 17:35:27 标签:.NET DDD 驱动设计 原创作品,允许转载,转载时请务必以超链接形式标明 ...

随机推荐

  1. Oracle11g R2创建PASSWORD_VERIFY_FUNCTION相应password复杂度验证函数步骤

    Oracle11g R2创建PASSWORD_VERIFY_FUNCTION相应密码复杂度验证函数步骤 运行測试环境:数据库服务器Oracle Linux 5.8 + Oracle 11g R2数据库 ...

  2. Android使用Fragment,不能得到Fragment内部控件,findViewById()结果是Null--已经解决

    程序很easy.好长时间没有搞定.郁闷.... . .... . . . 在论坛咨询,最终找到答案. 描写叙述: 一个Activity:MainActivity.内部是一个Fragment:Fragm ...

  3. Pleasant sheep and big big wolf

    pid=3046">点击打开链接 题目:在一个N * M 的矩阵草原上,分布着羊和狼.每一个格子仅仅能存在0或1仅仅动物.如今要用栅栏将全部的狼和羊分开.问怎么放,栅栏数放的最少,求出 ...

  4. [Project Euler 409] Nim Extreme 解题报告 (统计方案数)

    题目链接:https://projecteuler.net/problem=409 题目: 题解: 题目问你必胜态的数目,我们考虑用总的方案数减去必败态的方案数(NIM游戏没有平局这个操作) 必败态的 ...

  5. [JZOJ3385] [NOIP2013模拟] 黑魔法师之门 解题报告(并查集)

    Description 经过了16个工作日的紧张忙碌,未来的人类终于收集到了足够的能源.然而在与Violet星球的战争中,由于Z副官的愚蠢,地球的领袖applepi被邪恶的黑魔法师Vani囚禁在了Vi ...

  6. strlen() 和 sizeof() 的区别

    1.strlen() 时函数,他在程序运行时才能计算.它的参数类型要求时 char *,且必须是以'/0'结尾.数组在传入时已经退化为指针.它的作用是返回数组中字符串的长度. 2.sizeof()时运 ...

  7. asp.net网页播放MP4 出错

    通过IIS进行添加:单击[开始]→[程序]→[管理工具]→[IIS管 理器],逐步展开“本地计算机”.“网站”,在你的网站上右击,选择[属性],单击“HTTP头”选项卡→单击“MIME类型”按钮,再单 ...

  8. SQL流程控制语句

    1 GoTo语句 IF 12>9GOTO print1ELSE GOTO print2 print1:PRINT '执行了流程1'--GOTO theEndprint2:PRINT '执行了流程 ...

  9. yii2-Ueditor百度编辑器

    今天在网上看了下有关图片上传的教程,历经挫折才调试好,现在把相关代码及其说明贴出来,以供初次使用的朋友们参考. 资源下载 yii2.0-ueditor下载路径: https://link.jiansh ...

  10. [BJOI2018]求和(树链剖分)

    题目描述 master 对树上的求和非常感兴趣.他生成了一棵有根树,并且希望多次询问这棵树上一段路径上所有节点深度的 kkk 次方和,而且每次的 kkk 可能是不同的.此处节点深度的定义是这个节点到根 ...