一、需求

app打包需要打入一些H5进去,以便更快的加载页面。这些H5文件是散落在各个文件夹中的【如下列所示】,偶尔各个文件夹还需新增文件,每次新增一个文件,需要改动jenkins上job脚本,比较麻烦,所以换一种思路来解决这个问题。

tmp/
├── c
│   ├── cmd.js.d
│   ├── TZT2..js.d
│   ├── TZT.js.d
│   └── TZT\\\\\\\\\\\\.json.d
├── c_modules
│   ├── config.js.d
│   ├── css
│   │   ├── base-min2..css.d
│   │   ├── base-min.css.d
│   │   ├── base-min-white.css.d
│   │   ├── images
│   │   │   └── arrow.png.d
│   │   ├── jskj-elementUI.css.d
│   │   ├── scroller.css.d
│   │   ├── skin
│   │   │   └── bg.css.d
│   │   └── skin01
│   │   └── bg.css.d
│   ├── debuggap.js.d
│   ├── fastclick.js.d
│   ├── heatmap.min.js.d
│   ├── jquery-1.7..min.js.d
│   ├── jquery.min.js.d
│   ├── loadData.js.d
│   ├── loadSel.js.d
│   ├── onscroll.js.d
│   ├── pop
│   │   ├── images
│   │   │   └── icon_closeBtn.png.d
│   │   ├── pop.css.d
│   │   ├── pop.js.d
│   │   ├── pop-zdycx.css.d
│   │   └── pop-zdycx.js.d
│   ├── proint.js.d
│   ├── sea.js.d
│   └── sensorsdata.min.js.d
├── config
│   └── index.js.d
├── dist
│   ├── src
│   │   ├── common
│   │   │   ├── iconClick.js.d
│   │   │   └── md5.js.d
│   │   ├── home
│   │   │   ├── app.js.d
│   │   │   ├── images
│   │   │   │   ├── close.png.d
│   │   │   │   ├── default.png.d
│   │   │   │   ├── down.png.d
│   │   │   │   ├── dxsq.png.d
│   │   │   │   ├── fxng.png.d
│   │   │   │   ├── gpcc.png.d
│   │   │   │   ├── gpkh.png.d
│   │   │   │   ├── guide1.png.d
│   │   │   │   ├── guide2.png.d
│   │   │   │   ├── guide3.png.d
│   │   │   │   ├── guide4.png.d
│   │   │   │   ├── header_bg.png.d
│   │   │   │   ├── jftoast.png.d
│   │   │   │   ├── mid_xgsgts.png.d
│   │   │   │   ├── myzc.png.d
│   │   │   │   ├── new.png.d
│   │   │   │   ├── news.png.d
│   │   │   │   ├── nodata.png.d
│   │   │   │   ├── oper_activity_pop.png.d
│   │   │   │   ├── register_tel.png.d
│   │   │   │   ├── right.png.d
│   │   │   │   ├── rmzt_one.png.d
│   │   │   │   ├── rmzt_three.png.d
│   │   │   │   ├── rmzt_two.png.d
│   │   │   │   ├── selected.png.d
│   │   │   │   ├── select.png.d
│   │   │   │   ├── shadow.png.d
│   │   │   │   ├── tougu_bg.png.d
│   │   │   │   ├── up.png.d
│   │   │   │   ├── user.png.d
│   │   │   │   ├── voice.gif.d
│   │   │   │   ├── yszb.png.d
│   │   │   │   └── ywbl.png.d
│   │   │   ├── index.html.d
│   │   │   ├── js
│   │   │   │   ├── home_index.js.d
│   │   │   │   └── Sortable.js.d
│   │   │   ├── routes
│   │   │   │   └── routes.js.d
│   │   │   ├── skin01
│   │   │   │   └── home_index.css.d
│   │   │   └── template
│   │   │   └── home_index.html.d
│   │   ├── mine
│   │   │   ├── api
│   │   │   │   └── function.js.d
│   │   │   ├── app.js.d
│   │   │   ├── css
│   │   │   │   └── index.css.d
│   │   │   ├── img
│   │   │   │   ├── arrow_account.png.d
│   │   │   │   ├── cao.png.d
│   │   │   │   ├── common_used.png.d
│   │   │   │   ├── crown.png.d
│   │   │   │   ├── detail.png.d
│   │   │   │   ├── dui.png.d
│   │   │   │   ├── flow.png.d
│   │   │   │   ├── guide1.png.d
│   │   │   │   ├── guide2.png.d
│   │   │   │   ├── guide3.png.d
│   │   │   │   ├── guide4.png.d
│   │   │   │   ├── guide5.png.d
│   │   │   │   ├── hide_assets.png.d
│   │   │   │   ├── jcsc.png.d
│   │   │   │   ├── ka.png.d
│   │   │   │   ├── not_login.png.d
│   │   │   │   ├── show_assets.png.d
│   │   │   │   ├── sign.png.d
│   │   │   │   ├── transfer_accounts.png.d
│   │   │   │   ├── tui.png.d
│   │   │   │   ├── vip_arrow.png.d
│   │   │   │   ├── vip.png.d
│   │   │   │   ├── wei.png.d
│   │   │   │   └── wen.png.d
│   │   │   ├── index.html.d
│   │   │   ├── js
│   │   │   │   └── index.js.d
│   │   │   ├── routes
│   │   │   │   └── routes.js.d
│   │   │   ├── skin
│   │   │   │   └── index.css.d
│   │   │   ├── skin01
│   │   │   │   └── index.css.d
│   │   │   └── template
│   │   │   └── index.html.d
│   │   └── public-images
│   │   ├── cccb.png.d
│   │   ├── dkxh.png.d
│   │   ├── dpjl.png.d
│   │   ├── dtzq.png.d
│   │   ├── dxsq.png.d
│   │   ├── dzjy.png.d
│   │   ├── fhsp.png.d
│   │   ├── fxng.png.d
│   │   ├── fxspg.png.d
│   │   ├── gdrs.png.d
│   │   ├── ggcg.png.d
│   │   ├── ggtjy.png.d
│   │   ├── ggt.png.d
│   │   ├── gpcc.png.d
│   │   ├── gpkh.png.d
│   │   ├── gpqq.png.d
│   │   ├── gsrl.png.d
│   │   ├── gszx.png.d
│   │   ├── gznhg.png.d
│   │   ├── jcsc.png.d
│   │   ├── jfsc.png.d
│   │   ├── jgdy.png.d
│   │   ├── jjzt.png.d
│   │   ├── lcsc_new.png.d
│   │   ├── lhb.png.d
│   │   ├── mfjg.png.d
│   │   ├── myzc.png.d
│   │   ├── nrzt.png.d
│   │   ├── qbfw.png.d
│   │   ├── rmzt.png.d
│   │   ├── rzrq.png.d
│   │   ├── sczd.png.d
│   │   ├── sjjj.png.d
│   │   ├── ssnc.png.d
│   │   ├── tfp.png.d
│   │   ├── tgsq.png.d
│   │   ├── xsjj.png.d
│   │   ├── xskx.png.d
│   │   ├── xyjy.png.d
│   │   ├── yjyg.png.d
│   │   ├── ywbl_old.png.d
│   │   ├── ywbl.png.d
│   │   ├── yzzz.png.d
│   │   ├── zlcc.png.d
│   │   ├── znxg.png.d
│   │   ├── znyj.png.d
│   │   └── znzg.png.d
│   └── static
│   ├── css
│   │   ├── base.css.d
│   │   ├── base-min.css.d
│   │   ├── base-min-sea-vue.css.d
│   │   ├── mobiscroll.custom-2.6..min.css.d
│   │   └── swiper.css.d
│   ├── jquery
│   │   ├── jquery-1.11..min.js.d
│   │   ├── jquery-1.8..min.js.d
│   │   └── jquery-range.js.d
│   ├── lib
│   │   ├── action.js.d
│   │   ├── flexible.js.d
│   │   ├── mobiscroll.custom-2.6..min.js.d
│   │   └── swiper.js.d
│   ├── sea
│   │   ├── sea.js.d
│   │   └── seajs-text.js.d
│   └── vue
│   ├── vue.js.d
│   ├── vue-router.min.js.d
│   ├── vue-scroller.min.js.d
│   └── vue-scroller.min.js.map.d
├── frontend_7_06_js_test_0303.7z
└── jy
└── ggqq
├── function
│   └── function.js.d
├── ggqq_index.html.d
├── image
│   ├── add.png.d
│   ├── delete.png.d
│   ├── drcj.png.d
│   ├── fall.png.d
│   ├── ggqq_chicang.png.d
│   ├── ggqq_cljy.png.d
│   ├── ggqq_index_b.png.d
│   ├── ggqq_index.png.d
│   ├── ggqq_kcwt.png.d
│   ├── ggqq_ksxd.png.d
│   ├── ggqq_minus.png.d
│   ├── ggqq_nologin.png.d
│   ├── ggqq_plus.png.d
│   ├── ggqq_sybg.png.d
│   ├── ggqq_xq.png.d
│   ├── gou.png.d
│   ├── kcwt.png.d
│   ├── loading.gif.d
│   ├── minus.png.d
│   ├── mymoney.png.d
│   ├── notselect.png.d
│   ├── others@2x.png.d
│   ├── reset.png.d
│   ├── right2.png.d
│   ├── right.png.d
│   ├── rise.png.d
│   ├── select.png.d
│   ├── shoppingcar.png.d
│   └── zhcl@2x.png.d
├── js
│   └── ggqq_index.js.d
├── skin
│   ├── bdq.css.d
│   ├── chedan.css.d
│   ├── ggqq_bdsx.css.d
│   ├── ggqq_chicang.css.d
│   ├── ggqq_edcx.css.d
│   ├── ggqq_hylist.css.d
│   ├── ggqq_hysx.css.d
│   ├── ggqq_index.css.d
│   ├── ggqq_notice.css.d
│   ├── ggqq_qindex.css.d
│   ├── ggqq_xq.css.d
│   ├── ggqq_xycx.css.d
│   ├── ggqq_xyxq.css.d
│   ├── jsd.css.d
│   ├── login_mesg.css.d
│   ├── qchicang.css.d
│   ├── revisepassword.css.d
│   └── zjcc.css.d
└── skin01
├── bdq.css.d
├── ggqq_bankcr.css.d
├── ggqq_bdsx.css.d
├── ggqq_chicang.css.d
├── ggqq_edcx.css.d
├── ggqq_hylist.css.d
├── ggqq_hysx.css.d
├── ggqq_index.css.d
├── ggqq_notice.css.d
├── ggqq_qindex.css.d
├── ggqq_xq.css.d
├── ggqq_xycx.css.d
├── ggqq_xyxq.css.d
├── jsd.css.d
├── login_mesg.css.d
├── revisepassword.css.d
└── zjcc.css.d

二、思路

让前端开发把需要打入app的H5文件放入D:\scripts\src目录上  --->  读取该目录下文件的绝对路径  --->  在workspace中寻找对应的文件 ---> 并将这些文件复制到新的目录中,进行7za打包

python代码如下:

 #!/usr/bin/env python3
#-*- coding:GBK -*-
# author by Michael Ho
# contact:rui.he@geekthings.com.cn
import os, shutil def copy_app_H5_file(x_root, x_dir, src_dir, dst_dir):
if os.path.exists(dst_dir):
shutil.rmtree(dst_dir)
for root, dirs, files in os.walk(x_root):
for d_name in dirs:
d_name = os.path.join(root, d_name).rstrip()
d_dir = d_name.replace(x_dir, dst_dir)
if not os.path.exists(d_dir):
os.makedirs(d_dir)
for f_name in files:
f_name = os.path.join(root, f_name).rstrip()
if(os.path.splitext(f_name)[1] == ".d"):
s_file = f_name.replace(x_dir, src_dir)
d_file = f_name.replace(x_dir, dst_dir)
shutil.copyfile(s_file, d_file)
# 判断复制是否成功
if(s_file.replace(src_dir, "") == d_file.replace(dst_dir, "")):
print(d_file + "->" + "拷贝成功")
else:
print("拷贝过程发生错误,请检查...") if __name__ == '__main__':
# 上传的小包根目录,默认是d:\scripts,不要去动它!!!
x_root = "d:\\scripts" # 小包目录,默认是src,需要把小包的文件放在一个叫src目录里面!!!
x_dir = "d:\\scripts\\src" # 从gitlab上获取的目录
src_dir = "d:\\Jenkins\\frontend_encrypt" # 需要复制到目标目录,一般对其目录进行打包
dst_dir = "d:\\Jenkins\\H5_APP" copy_app_H5_file(x_root, x_dir, src_dir, dst_dir)

三、说明

1.在Jenkins客户端在Windows上,python编码格式要设定成    # -*- coding:GBK -*-  (笔者当时写的是 # -*- coding: utf-8 -*-)不然Jenkins会报以下错误

SyntaxError: (unicode error) 'utf-8' codec can't decode byte 0xbf in position 0: invalid start byte

2.python调系统级的接口不算太友好,个人认为没有批处理方便。如果整个文件夹复制的话,还是 xcopy  src_dir dst_dir /s /e /f方便,所以Jenkins上打包的脚本,笔者为了打包速度,Windows打包机采用batch+python【以上个人见解、水平有限】

python复制多层目录下的文件至其他盘符对应的目录中的更多相关文章

  1. rsync+inotify 实现资源服务器的同步目录下的文件变化时,备份服务器的同步目录更新,以资源服务器为准,去同步其他客户端

    测试环境: 资源服务器(主服务器):192.168.200.95 备份服务器(客户端):192.168.200.89 同步目录:/etc/test 同步时使用的用户名hadoop密码12345 实验目 ...

  2. PHP 批量获取指定目录下的文件列表(递归,穿透所有子目录)

    //调用 $dir = '/Users/xxx/www'; $exceptFolders = array('view','test'); $exceptFiles = array('BaseContr ...

  3. python统计目录和目录下的文件,并写入excel表

    运营那边提出需求,有些媒体文件需要统计下 目录结构大概是这样的 每个目录下面都有很多文件,目录下面没子目录 我这里是模拟下创建的目录和文件,和运营那边说的目录结构都是一致的 想最终统计结果如下格式 我 ...

  4. Python递归遍历目录下所有文件

    #自定义函数: import ospath="D:\\Temp_del\\a"def gci (path): """this is a stateme ...

  5. Python开发【笔记】:获取目录下所有文件

    获取文件 import os def sub_dirs(rdir): li = os.listdir(rdir) return li def main(rdir): content = sub_dir ...

  6. python实现指定目录下批量文件的单词计数:并发版本

    在 文章 <python实现指定目录下批量文件的单词计数:串行版本>中, 总体思路是: A. 一次性获取指定目录下的所有符合条件的文件 -> B. 一次性获取所有文件的所有文件行 - ...

  7. Python打开目录下所有文件

    用Python打开指定目录下所有文件,统计文件里特定的字段信息. 这里是先进入2017-02-25到2017-03-03目录,然后进入特定IP段目录下,最后打开文件进行统计 import os, gl ...

  8. Python遍历目录下所有文件的最后一行进行判断若错误及时邮件报警-案例

    遍历目录下所有文件的最后一行进行判断若错误及时邮件报警-案例: #-*- encoding: utf-8 -*- __author__ = 'liudong' import linecache,sys ...

  9. Python 读取某个目录下的文件

    读取某个目录下的文件,如'/Users/test/test_kmls'目录下有test1.txt.test2.txt. 第一种方法读出的all_files是test1.txt.test2.txt im ...

随机推荐

  1. 线程池-进程池-io模型

    一.线程池与进程池 什么是池?简单的说就是一个容器,一个范围 在保证计算机硬件安全的情况下最大限度的充分利用计算机, 池其实是降低了程序的运行效率,但是保证了计算机硬件的安全,也是实现了一个并发的效果 ...

  2. GIL全局解释器锁-死锁与递归锁-信号量-event事件

    一.全局解释器锁GIL: 官方的解释:掌握概念为主 """ In CPython, the global interpreter lock, or GIL, is a m ...

  3. ZJNU 1153 - 找单词——中级

    状态转移b[i]记录价值为i的单词种类数d[j+k*i]+=b[j] , k<=a[i]&&j+k*i<=50表示价值为j+k*i的单词可以由价值为j的单词加上k个i字母转 ...

  4. Linux Centos下MySQL主从Replication同步配置(一主一从)

    MySQL 主从复制概念MySQL 主从复制是指数据可以从一个MySQL数据库服务器主节点复制到一个或多个从节点.MySQL 默认采用异步复制方式,这样从节点不用一直访问主服务器来更新自己的数据,数据 ...

  5. Mybatis+Druid多数据源配置

    在日常开发中我们可能会用到多数据源开发,什么是多数据源? 简单来讲的话,就是一个项目连接多个数据库.当然只是可能会用到,我暂时没见过应用场景,但是还是了解学习一下 此项目可以基于上一个简单集成项目进行 ...

  6. sql的书写顺序

    例:select t.* from (select *  from t_user where isDelete = 1 limit 0,10) t order by t.qq select from ...

  7. 迅为iTOP-4418开发板编译Ubuntu

    Ubuntu 系统比较特殊,源码就是它的镜像.Ubuntu 系统通过解压的方式进行烧写,我们也可以通过配置解压出来的 Ubuntu 系统源码文件夹,来配置 Ubuntu 系统.然后通过打包压缩的方式来 ...

  8. [APIO2009-C]抢掠计划

    题:https://www.cometoj.com/problem/0461 分析:求边双,最后求多汇点最长路 #include<iostream> #include<cstring ...

  9. 吴裕雄--天生自然python学习笔记:python的Bokeh 基本绘图

    使用 Bokeh 绘图时,其大部分绘图功能是由 bokeh plotting 完成的,所以我们一 般至少要导入自gure 及 show 这两个函数 : Bokeh 绘制的图形是在浏览器中显示的, 创建 ...

  10. Qt QString的arg()方法的使用

    1.QString的arg()方法用于填充字符串中的%1,%2...为给定的参数,如 QString m = tr("); // m = "12:60:60: 2.它还有另外一种重 ...