for循环批量处理文件名 | 您所在的位置:网站首页 › 怎么批量修改文件前缀名 › for循环批量处理文件名 |
在linux中批量处理文件名,是十分容易的操作。有多种方法与手段,如mv、rename、prename、sed和awk等。我们前面两篇文章《linux centos7中批量修改文件名》和《awk批量修改文件名》进行了讨论。可供参考。 本文从学习bash变量和变量子串操作为基础,从批量处理文件名为项目上,讨论分支语句和循环语句。 一、相关变量和代码 1.变量bash中的变量是bash命令与编程的基础。 定义与应用 不用事先声明,直接使用。 变量不分数据类型,均以字符串为标准。 变量定义 变量名=变量值,如name=zhang3;age=18 打印变量 echo $name 或者 echo ${age} 双方括号: [[ ]] 用于字符串比较的正则匹配, 用于变量的模糊匹配与精确匹配。 变量子串 格式:${变量} 主要的作用:变量子串的效率要比相应的命令执行的效率高 变量的长度 ${#变量} 变量子串截取 打印指定开始位置的字符串长度,${变量:3} 从第三个字符到结尾保留(包含空格且不算第三个字符) 也可以制定从哪个字段开始取,取多少字段 ${变量:3:5} 变量子串匹配删除 #表示从开头删除匹配最短 ##表示从开头删除匹配最长 %表示从结尾删除匹配最短 %%表示从结尾删除匹配最长 变量子串替换 使用/代替第一个指定匹配的字符并替换 使用//代替所有匹配的指定字符串 2.分支语句正常命令的执行顺序都是从前向后依序执行。只有当使用分支语句时,可以改变代码执行的方向与前后顺序。 分支语句是编程里的一个基础且重要的语法语句,执行的路径会被分成两条,再加上限制条件或者判定条件,将执行不同的代码,有if语句、else、switch语句、defualt子句。 分支分类 a.单分支 if [ ];then fi b.双分支 if [ ];then else fi c.多分支 if [ ];then elif else fi 3.循环语句循环语句有重要的几类:for while do while until switch case等。 最常用的是for和while。 for命令是linux自带的命令,能够实现对文件或者目录的批量重命名。 for命令的一般格式: for file in files_list; do command;done files_list表示准备重命名的文件或者目录的列表,command表示要执行的命令,该命令不仅可以用来实现文件或者目录的批量重命名,还能实现即时重命名文件和目录,当前文件或者目录依然保持完整。 循环之间可以嵌套,循环与分支配合,应用广泛。 我们说,for循环是一切编程的基础;单条命令是基础,多项组合构成脚本,分支语句与循环语句的巧妙运用,完成一个项目上。深刻理解命令是一批系统调用的集合,人机交互的抓手,bash或shell是常用的支架或工具。 二、项目训练 1.思路在项目中学习命令与流程控制。 批量处理文件名,离不开循环。而for循环是最主要的! 本文的主要目的:通过for循环使用与训练,抓住问题的关键,寻根问底,追求举一反三。 在解决项目的过程中,用到多个命令,每项命令又有很多选项,其参数也有变化。只有多用多练命令,才可处理复杂的棘手问题。 2.for循环的原理a.解决文件的表达 查出文件,或列表显示文件 b.选择命令的使用 可选择ls ll,也可以选择find grep等 c.循环条件的设计 循环常用for和while。我们主要选择for。 for file in `ls *.conf`; do mv $file ${file%.*}.cpp;done 代码作用是批量修改后缀.conf为后缀.cpp 批量处理文件名,主要是对原有文件名的增删改。其中涉及后缀、路径和文件名。 a、替换 改变文件的后缀,是常见的工作需要,也是最简单的修改。 b、添加 ps:linux下批量改变文件前缀命令 for f in * ; do mv -- "$f" "PRE_$f" ; done 包括在后缀后再添加后缀,前缀前再加前缀,文件名中添加标志性字符。 c、修改 有的文件名添加有多项说明性文字或日期或项目编号等,一定条件下,需要变为其他名称。 d、组合 添加前后缀与标志性关键词,删除不需要的术语或编号,多项要求与组合。 e、拆分 有些符号或标志不合适,更改为新的符号。 具体案例要求前两篇文章相同,以不同的方法与思路,解决同一个问题。 1.把当前目录下的.conf文件全部修改为.txt文件 2.把当前目录下的test开头的文件全部修改为demo开头的文件 3.调整当前目录下子目录下的2022-05-01等含日期的文件为_分隔的文件 4.将当前目录下所有子目录下以a开头的.cpp文件修改为以b开头的.c文件 5.将当前目录下所有子目录下以ab开头的.sh文件修改为以AB开头的.py文件,并将所有.jpg文件修改为test_01.jpg等格式(序号按修改文件时间排列) 4.代码与说明查找当前目录下文件 ls *.conf 形成文件列表 `ls *.conf` 或者$(ls *.conf) 可以赋值给一个变量lt=`ls *.conf` 设计一个for循环: for f in lt do 循环代码 done 查找当前目录下文件及子目录下文件 find ./ -name “*.conf” 如果是查询两个后缀的文件 find ./ -name “*.conf” -o –name “*.txt” 如果是查询多个后缀的文件(建议用扩展正则) find ./ -regextype posix-extended -regex “*\.\(conf|txt|cpp\)” 改变文件后缀 a.创建一个新变量,接收重命名的文件 newfile=`echo $f |rename .conf .txt` newfile=`echo $f |sed 's/.conf/.txt/'` mv -f $f $newfile b.在用mv重命名时,修改变量子串 mv -f $f ${f%.*}.txt 建议:简单修改文件名后缀,用b方法;一般性修改文件名,用a方法。 修改前缀 把当前目录下的test开头的文件全部修改为demo开头的文件 同前一案例,两个方法均可(不论调整何处的字符串都可以) for f in $(ls test*) do mv -f $f ${f/test/demo} done 如何处理当前目录及子目录下的文件,可以改ls查找文件为find命令,多路径查找。 对于替换首字符或首单词情况,可以如此处理: for f in $(ls test*) do mv -f $f "demo"${f:4} done $(f:4)表示保留原变量的第4位至尾部字符 调整格式 调整当前目录下子目录下的2022-05-01等含日期的文件为_分隔日期的文件 与前两类案例相比,增加一点难度: 把单次替换改为全局替换!用变量子串时,用双/(//);用sed替换时,格式为's///g' for f in `find ./ -name "*-??-*"` do mv -f $f ${f//-/_} done 高难度修改 将当前目录下所有子目录下以a开头的.cpp文件改名为以b开头的.c文件 本案例有难度,但通过前述两个方法的组合,可以解决。 for f in `find ./ -name "a*.cpp"` do newfile=`echo $f | sed 's/.cpp/.c/'` mv -f $f ${newfile/a/b} done 相互交换一下才成立。 for f in `find ./ -name "b*.c"` do newfile=`echo $f | sed 's/b/a/'` mv -f -v $f ${newfile%.*}.cpp done -f 强制修改 -v 显示过程 复杂修改 将当前目录下所有子目录下以ab开头的.sh文件修改为以AB开头的.py文件,并将所有.jpg文件修改为test_01.jpg等格式(序号按修改文件时间排列) 这是较为复杂的案例。主要是使用分支语句: 分支1 处理.sh文件 分支2 处理.jpg文件 操作实践表明:同时处理两类文件时,不能使用双分支语句,多分支语句更无法使用。 另外,在对两个变量进行模糊匹配时,只能把文件名变量放在前面,文件名后缀作为变量,只能放在后面。 基本格式: if [[ $f =~ $a ]];then echo $f echo ++++++++++++ mv $f "prefix_"${f%.*}.jpg fi 如果在变量中添加序列类数字,需要在for循环前定义变量x,循环时添加x++ x=0 for f in `ls ab*.sh *.jpg` do a=".sh" b=".jpg" if [[ $f =~ $a ]];then newfile=`echo $f | sed 's/py/sh/'` mv $f "AB"${f#ab} fi if [[ $f =~ $b ]];then let x++ mv $f test$x".jpg" fi done |
CopyRight 2018-2019 实验室设备网 版权所有 |