当前位置: 首页 > news >正文

.bat批处理(五):遍历指定目录下资源文件并更新

前言

先来看这样一个需求,假设有A,B两个目录,其中A目录是资源目录,B目录是工作目录,其中资源目录不定期更新,资源文件都在A目录下,并且没有子目录层级关系,但是资源要被使用时需要更新到B工作目录,B目录根据工程需要建立了一个包含众多子目录的层级体系,这样当A目录中的一个资源文件更新后,需要手动复制A目录中更新的资源文件,然后在B目录中找到对应的位置,然后进行粘贴替换,这样的操作如果很久一次、或者每次只有1、2个文件还好,如果资源文件大范围更新,那么要一个个找到更新文件在B目录中的位置然后替换就成了一件令人苦恼的事情,所以根据这个需求,才有了下面的探索过程。

思路的转变

一开始想把A目录作为出发点,毕竟A目录中包含了修改后的资源文件,但是A目录更新后怎样才能准确的修改对应的B目录呢?我想到了配表,每次新增资源后,都会修改配置表,将A目录中的各个文件资源与B目录中的位置建立对应关系,这样A目录下的资源更新后就可以根据配置文件统一更新B目录了。

但这样的做法就是,需要经常维护配置文件,特别是增加或者删除资源的时候,然后我就想到了现在的这个做法,从B目录出发,注意本文主要解决的是资源文件的更新,而不是新增,更新就说明是原有的文件,只是内容发生了变化,比如一些UI文件,这些文件经常会做布局格式的调整,控件的增加和删除等等,调整结束后需要更新到工作目录。

实现过程

实现的过程并没有想象的那么顺利,期间遇到了诸多问题和一些新的概念,比如for循环的语法,for循环中的变量定义,if条件的语法,字符串变量的替换,文件目录的处理,延迟环境变量扩展等等,这些问题每一项都可以作为一个单独的知识点,后续我会抽时间慢慢总结到一起,总之最后终于可以用了,前后大约花了1个半小时的时间,想想也是醉了,下面是一个具体的示例及对应的实现代码。

  1. A资源目录对应实际的”E:/dirZ”,结构如下:

    root:[E:/dirZ]
    +--aaa.txt
    +--bbb.txt
    +--ccc.txt
    +--ddd.txt
    +--eee.txt
    +--extra.c
    +--extra.h
    +--fff.txt
    +--ggg.txt
  2. B工作目录对应实际的”E:/dirA”,结构如下:

    root:[E:/dirA]
    +--aaa.txt
    +--bbb.txt
    +--dirB
    |    +--ccc.txt
    |    +--extra.c
    |    +--extra.h
    +--dirC
    |    +--ddd.txt
    |    +--dirD
    |    |    +--eee.txt
    +--dirE
    |    +--dirF
    |    |    +--fff.txt
    |    |    +--ggg.txt
  3. 现在需要把E:/dirZ目录中的txt文件,按照E:/dirA目录的层级结构,更新到对应位置,并且不更新ggg.txt文件,以下是实现的代码:

    @echo off
    
    rem 启用延迟环境变量扩展
    setlocal enabledelayedexpansion
    
    rem 定义不需要更新的文件
    SET EXCEPT_FILE=ggg.txt
    
    rem 定义工作目录和资源目录
    SET WORK_PATH=E:\dirA\
    SET RESO_PATH=E:\dirZ\
    
    rem 简单输出查看一下
    echo WORK_PATH is %WORK_PATH%
    echo RESO_PATH is %RESO_PATH%
    echo ------------------------
    
    rem for循环递归遍历WORK_PATH目录中的.txt文件,文件的全路径放在变量f中
    for /R %WORK_PATH% %%f in (*.txt) do (
     rem 使用TARGET_FILE变量记录绝对文件名,注意延迟变量的使用
     SET TARGET_FILE=%%f
     echo !TARGET_FILE!
    
     rem 去掉路径,只保留文件名及扩展名
     SET "FILE_PATH_NO_EXT=%%~nxf"
     rem 利用资源路径和文件名,拼接出资源的绝对全路径
     SET SOURCE_FILE=%RESO_PATH%!FILE_PATH_NO_EXT!
     echo !SOURCE_FILE!
    
     rem 条件判断是否是不需要更新的文件
     if NOT !FILE_PATH_NO_EXT!==%EXCEPT_FILE% (
         copy !SOURCE_FILE! !TARGET_FILE!
     )
    )
    pause
  4. 运行结果

    WORK_PATH is E:\dirA\
    RESO_PATH is E:\dirZ\
    <hr />
    
    E:\dirA\aaa.txt
    E:\dirZ\aaa.txt
    已复制         1 个文件。
    E:\dirA\bbb.txt
    E:\dirZ\bbb.txt
    已复制         1 个文件。
    E:\dirA\dirB\ccc.txt
    E:\dirZ\ccc.txt
    已复制         1 个文件。
    E:\dirA\dirC\ddd.txt
    E:\dirZ\ddd.txt
    已复制         1 个文件。
    E:\dirA\dirC\dirD\eee.txt
    E:\dirZ\eee.txt
    已复制         1 个文件。
    E:\dirA\dirE\dirF\fff.txt
    E:\dirZ\fff.txt
    已复制         1 个文件。
    E:\dirA\dirE\dirF\ggg.txt
    E:\dirZ\ggg.txt
    请按任意键继续. . .

总结

到此为止我们就解决了这个资源更新的实际问题,每次资源更新后只要运行这个批处理文件就可以更新工作目录中对应的资源文件了,在这个例子中关于目录的截取,一开始走了很多弯路,其实有很多现成的方式,所以需要在此记录一下,方便以后查找使用,具体查看示例代码:

ECHO off
SETlOCAL enabledelayedexpansion

SET FIND_DIR=E:\dirA\dirC\dirD

for /R %FIND_DIR% %%f in (*.txt) do (
    SET FULL_PATH=%%f
    ECHO 完整的路径: !FULL_PATH!

    SET FILE_DIR=%%~dpf
    ECHO 所在的目录: !FILE_DIR!

    SET FILE_NAME=%%~nf
    ECHO 无后缀文件: !FILE_NAME!

    SET FILE_EXT=%%~xf
    ECHO 文件名后缀: !FILE_EXT!

    SET "FILE_NAME_NOT_PATH=%%~nxf"
    ECHO 无路径文件: !FILE_NAME_NOT_PATH!

    SET "FULL_PATH_NOT_EXT=%%~dpnf"
    ECHO 无后缀全名: !FULL_PATH_NOT_EXT!
)
pause

运行结果:

完整的路径: E:\dirA\dirC\dirD\eee.txt
所在的目录: E:\dirA\dirC\dirD\
无后缀文件: eee
文件名后缀: .txt
无路径文件: eee.txt
无后缀全名: E:\dirA\dirC\dirD\eee

相关文章:

  • 神秘莫测的时间复杂度
  • 排序算法系列之(三)——略显神秘的快速排序
  • .bat批处理(六):替换字符串中匹配的子串
  • 操作指向类成员的指针需要了解的两个操作符-*和.*
  • VS2015调试dump文件时提示未找到xxx.exe或xxx.dll
  • 结构体sockaddr、sockaddr_in、sockaddr_in6之间的区别和联系
  • 简述TCP三次握手和四次挥手流程
  • 智能指针(零):分类及简单特性
  • 智能指针(一):auto_ptr浅析
  • 智能指针(二):shared_ptr浅析
  • 智能指针(四):unique_ptr浅析
  • Lua中关于table对象引用传递的注意事项
  • VS2015调试dump文件时提示打不开KERNELBASE.dll
  • Mysql中使用select into语句给变量赋值没有匹配记录时的结果
  • 排序算法系列之(四)——抓扑克牌风格的插入排序
  • 【跃迁之路】【519天】程序员高效学习方法论探索系列(实验阶段276-2018.07.09)...
  • angular2 简述
  • AngularJS指令开发(1)——参数详解
  • Electron入门介绍
  • iOS动画编程-View动画[ 1 ] 基础View动画
  • miaov-React 最佳入门
  • SAP云平台里Global Account和Sub Account的关系
  • springMvc学习笔记(2)
  • Stream流与Lambda表达式(三) 静态工厂类Collectors
  • -- 查询加强-- 使用如何where子句进行筛选,% _ like的使用
  • 分布式事物理论与实践
  • 关于Android中设置闹钟的相对比较完善的解决方案
  • 基于Android乐音识别(2)
  • 记一次用 NodeJs 实现模拟登录的思路
  • 扑朔迷离的属性和特性【彻底弄清】
  • 巧用 TypeScript (一)
  • 吴恩达Deep Learning课程练习题参考答案——R语言版
  • 以太坊客户端Geth命令参数详解
  • 因为阿里,他们成了“杭漂”
  • ​html.parser --- 简单的 HTML 和 XHTML 解析器​
  • ​一、什么是射频识别?二、射频识别系统组成及工作原理三、射频识别系统分类四、RFID与物联网​
  • #NOIP 2014# day.1 T2 联合权值
  • (delphi11最新学习资料) Object Pascal 学习笔记---第7章第3节(封装和窗体)
  • (html5)在移动端input输入搜索项后 输入法下面为什么不想百度那样出现前往? 而我的出现的是换行...
  • (Matlab)遗传算法优化的BP神经网络实现回归预测
  • (zhuan) 一些RL的文献(及笔记)
  • (博弈 sg入门)kiki's game -- hdu -- 2147
  • (二十五)admin-boot项目之集成消息队列Rabbitmq
  • (附源码)node.js知识分享网站 毕业设计 202038
  • (附源码)springboot太原学院贫困生申请管理系统 毕业设计 101517
  • (篇九)MySQL常用内置函数
  • (一)ClickHouse 中的 `MaterializedMySQL` 数据库引擎的使用方法、设置、特性和限制。
  • (一)RocketMQ初步认识
  • (原創) 人會胖會瘦,都是自我要求的結果 (日記)
  • (转)Linux整合apache和tomcat构建Web服务器
  • (转载)OpenStack Hacker养成指南
  • .【机器学习】隐马尔可夫模型(Hidden Markov Model,HMM)
  • .CSS-hover 的解释
  • .NET/C# 使窗口永不获得焦点
  • .Net7 环境安装配置