`
lovnet
  • 浏览: 6710246 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

批量 文本内容替换, 改文件名 shell 脚本

 
阅读更多

原文:批量文本内容替换, 改文件名 shell 脚本
作者:Breaker <breaker.zy_AT_gmail>


写了个 shell 脚本 repren.sh,替换当前目录下的文本文件(根据扩展名、文件名决定)中的字符串 OLD_TEXT 为 NEW_TEXT,将含 OLD_TEXT 的文件名重命名为 NEW_TEXT

用途例子:改变 VC 工程中的工程名
改进说明:可将 FIND_REGEX(文件扩展名)、SED_REGEX(文本边界)、GREP_REGEX(文件名边界)的选择作为脚本命令选项, 或从另一文件中读取配置
限制说明:只是个文本替换小模型,没测中文

功能

假设如此调用脚本 repren.sh:

OLD_TEXT=Tom
NEW_TEXT=Jerry

按顺序做以下一些事:

1. 查找目录及子目录中的以下文件(大小写无关):

  • 文件名是:makefile、readme

  • 扩展名是:

    .h、.hxx、.hpp、.c、.cpp、.cxx
    .txt
    .mak、.rc
    .xml、.html、.xhtml
    .sln、.vcproj

查找的文件名正则表达式规则在 FIND_REGEX 中定义

2. 将找到的文件中的文本 Tom 替换为 Jerry:

Tom => Jerry: 严格大小写替换
TOM => JERRY: 全大写替换
tom => jerry: 全小写替换

但不替换:
tOm => Jerry: 混合大小写替换

Tom 两边可以有新行、空格、TAB、数字 0-9,以及这些 ASCII 标准标点符号

此时都可成功替换

但不能替换:
aaTombb => aaJerrybb
此时可修改 SED_REGEX='\(\b\|[0-9a-zA-Z_]\)',上面替换即可成功进行,但也会做下面替换:
Tomorrow => Jerryorrow

2. 对上面的文件,如果文件名中含 Tom,将其重命名为 Jerry

重命名支持混合大小写替换,即:
tOm_test.cpp => Jerry_test.cpp

重命名时,Tom 两边可以有的字符和 1 相同
不能替换:
TomTest.cpp => JerryTest.cpp
此时可修改 GREP_REGEX='(\b|[0-9a-zA-Z_]),但也会做下面替换:
Tomorrow.cpp => Jerryorrow.cpp

3. 对于当前目录下的所有子目录的目录名,做和 2 相同的事

shell 脚本代码

#!/bin/bash

################################################################################
# Name: repren.sh
# Description:
# 按顺序做以下事情:
# 1. 查找特定类型的文件,如 .h、.cpp
# 2. 将文件内容中的文本 OLD_TEXT 替换成 NEW_TEXT
# 3. 将含 OLD_TEXT 的文件名重命名为 NEW_TEXT
# 4. 将含 OLD_TEXT 的目录名重命名为 NEW_TEXT
#
# Author: Breaker <breaker.zy_AT_gmail>
# Date: 2011-10
################################################################################

# IFS 表示 for 语句中各项之间的分隔符
OLDIFS=$IFS
IFS=$'\n'# $ 使字面量启动转义,否则 \n 为直接字面量而非 LF
SCRIPT_NAME=`basename"$0"`

# 用法
usage()
{
echo "usage:"
echo " $SCRIPT_NAME OLD_TEXT NEW_TEXT"
}

if [ $# -lt 2 ];then
usage
exit -1
fi

# 替换前后的 文本
OLD_TEXT="$1"
NEW_TEXT="$2"

OLD_TEXT_UPPER=`echo$OLD_TEXT | tr'[a-z]' '[A-Z]'`# 全大写的 旧文本
OLD_TEXT_LOWER=`echo$OLD_TEXT | tr'[A-Z]' '[a-z]'`# 全小写的 旧文本

NEW_TEXT_UPPER=`echo$NEW_TEXT | tr'[a-z]' '[A-Z]'`# 全大写的 新文本
NEW_TEXT_LOWER=`echo$NEW_TEXT | tr'[A-Z]' '[a-z]'`# 全小写的 新文本

echo -e 'replace text & rename file ...\n'

# 查找指定文件
FIND_REGEX='.*(/(makefile|readme)|\.(h|hxx|hpp|c|cpp|cxx|txt|mak|rc|x(ht)?ml|html?|sln|vcproj))'
FILES=`find -type f -regextype posix-egrep -iregex"$FIND_REGEX"`

# 文本替换时的 字符串边界
#SED_REGEX='\(\b\|_\)'
SED_REGEX='\(\b\|[0-9_]\)'
#SED_REGEX='\(\b\|[0-9a-zA-Z_]\)'

# 重命名时的 文件名边界
#GREP_REGEX='(\b|_)'
GREP_REGEX='(\b|[0-9_])'
#GREP_REGEX='(\b|[0-9a-zA-Z_])'

# 对每个查找到的文件去做...
for EACH in $FILES
do
# 替换文件中的文本 OLD_TEXT 为 NEW_TEXT
sed -i "s/$SED_REGEX$OLD_TEXT$SED_REGEX/\1$NEW_TEXT\2/g"$EACH
sed -i "s/$SED_REGEX$OLD_TEXT_UPPER$SED_REGEX/\1$NEW_TEXT_UPPER\2/g"$EACH
sed -i "s/$SED_REGEX$OLD_TEXT_LOWER$SED_REGEX/\1$NEW_TEXT_LOWER\2/g"$EACH
echo "$EACH: replace: $OLD_TEXT => $NEW_TEXT"

# 重命名含 OLD_TEXT 的文件名为 NEW_TEXT
OLD_FILE_0=`basename$EACH | grep -E -i"$GREP_REGEX$OLD_TEXT$GREP_REGEX"`# 只针对文件名,不管目录部分
if [ "$OLD_FILE_0" !=""];then
DIR=`dirname$EACH`
OLD_FILE="$DIR/$OLD_FILE_0"

NEW_FILE_0=`echo"$OLD_FILE_0" | sed"s/$OLD_TEXT/$NEW_TEXT/gi"`
NEW_FILE="$DIR/$NEW_FILE_0"

mv "$OLD_FILE" "$NEW_FILE"
echo "rename: $OLD_FILE => $NEW_FILE"
fi

echo ''
done

echo -e 'rename dir ...\n'

# 更改目录名:重命名含 OLD_TEXT 的目录名
DIRS=`find -type d`
for EACH in $DIRS; do
OLD_DIR_0=`basename$EACH | grep -E -i"$GREP_REGEX$OLD_TEXT$GREP_REGEX"`
if [ "$OLD_DIR_0" !=""];then
OLD_DIR_DIR=`dirname$EACH`
OLD_OLD_DIR="$OLD_DIR_DIR/$OLD_DIR_0"

NEW_DIR_0=`echo"$OLD_DIR_0" | sed"s/$OLD_TEXT/$NEW_TEXT/gi"`
NEW_DIR_DIR=`echo"$OLD_DIR_DIR" | sed"s/$OLD_TEXT/$NEW_TEXT/gi"`

# find 先输出父目录,所以父目录这时已经重命名了
# 所以 OLD_DIR 由新的父目录名和 OLD_DIR_0 拼成,而不是原来的 OLD_OLD_DIR 了
OLD_DIR="$NEW_DIR_DIR/$OLD_DIR_0"
NEW_DIR="$NEW_DIR_DIR/$NEW_DIR_0"

mv "$OLD_DIR" "$NEW_DIR"
echo "rename: $OLD_OLD_DIR => $NEW_DIR"
echo ''
fi
done

# 恢复环境
IFS=$OLDIFS

相关工具

25 Text Batch Processing Tools Reviewed: 25 种文本批量处理工具评估,文本查找、替换、正则表达式支持

分享到:
评论

相关推荐

    大量批处理实用程序例程

    拼接相临的奇偶行文本内容.cmd 提取两个文件内容的不同之处.cmd 文本内容互换.bat 显示只有指定个数字符的行.cmd 显示某两个字符及其之间的字符.cmd 显示随机的5个数.cmd 查找偶数行内容.cmd 查找行中第一个数字串....

    700个批处理打包下载.rar

    反序列出文本的每行内容.cmd 反序显示输入内容.cmd 取得硬盘数.bat 变色+翻滚字符.bat 变色+翻滚字符.cmd 变量截取实例.bat 变量的多级嵌套.bat 变量的多级嵌套.cmd 只修改年份的批处理.bat 右键添加bat.bat 右键...

    1345个易语言模块

    世宝脚本语言引擎.ec 世恒通用安装系统文件压缩模块.ec 世恒通用安装系统文件压缩 模块RAR.EC 个性信息框.ec 个性信息框1.1.ec 个性信息框1.21.ec 个性信息框1.5.ec 个性 信息框1.ec 个性信息框1[1].21.ec 个性化...

    易语言程序免安装版下载

    “库文件名”以.lib或.obj为后缀的将被视为静态库,可使用绝对路径或相对路径(相对当前源代码所在目录),如依赖多个静态库请分别列出并以逗号分隔;“在库中的对应命令名”请务必准确填写静态库中公开导出的符号...

    Zen Cart 1.5.4 英文版.zip

    修正了撇号的代码在处理文件名修复#215 - 增加了更多的共同目的地curltester脚本修复#221 - 修正了优惠券和运费修复#246 - zc_install升级过程中修正有关密码错误发行 - 82 - (延续)修正奇PHP怪癖,从而引发...

    Zen Cart 1.5.4 中文版.zip

    修正了撇号的代码在处理文件名修复#215 - 增加了更多的共同目的地curltester脚本修复#221 - 修正了优惠券和运费修复#246 - zc_install升级过程中修正有关密码错误发行 - 82 - (延续)修正奇PHP怪癖,从而引发...

    1350多个精品易语言模块

    世宝脚本语言引擎.ec 世恒通用安装系统文件压缩模块.ec 世恒通用安装系统文件压缩 模块RAR.EC 个性信息框.ec 个性信息框1.1.ec 个性信息框1.21.ec 个性信息框1.5.ec 个性 信息框1.ec 个性信息框1[1].21.ec 个性化...

    易语言模块914个

    取腾讯TT浏览器的地址栏文本模块.ec 取非系统进程全路径文件名.ec 变速模块(1.0).EC 变速模块.ec 同步目录.ec 同步缩放控件.ec 同步缩放控件1.0.ec 同步缩放窗口1.0.ec 吸附模块.ec 和是几与谁最大.ec ...

    JAVA上百实例源码以及开源项目源代码

     可直接输入文件名或网络地址,但必需事先连入网络。 Java编写的山寨QQ,多人聊天+用户在线 21个目标文件 摘要:JAVA源码,媒体网络,山寨QQ,Java聊天程序  Java编写的山寨QQ,多人聊天+用户在线,程序分服务端和...

    JAVA上百实例源码以及开源项目

     可直接输入文件名或网络地址,但必需事先连入网络。 Java编写的山寨QQ,多人聊天+用户在线 21个目标文件 摘要:JAVA源码,媒体网络,山寨QQ,Java聊天程序  Java编写的山寨QQ,多人聊天+用户在线,程序分服务端和...

    java开源包1

    Port Groper可以与用测试防火墙,干扰web 统计脚本的跟踪,为网站增加流量..往好了用什么都能干,就是不能让一个网站下线。 FTP客户端Java类库 ftp4j ftp4j是一个FTP客户端Java类库,实现了FTP客户端应具有的大部分...

    java开源包11

    Port Groper可以与用测试防火墙,干扰web 统计脚本的跟踪,为网站增加流量..往好了用什么都能干,就是不能让一个网站下线。 FTP客户端Java类库 ftp4j ftp4j是一个FTP客户端Java类库,实现了FTP客户端应具有的大部分...

    java开源包2

    Port Groper可以与用测试防火墙,干扰web 统计脚本的跟踪,为网站增加流量..往好了用什么都能干,就是不能让一个网站下线。 FTP客户端Java类库 ftp4j ftp4j是一个FTP客户端Java类库,实现了FTP客户端应具有的大部分...

    java开源包3

    Port Groper可以与用测试防火墙,干扰web 统计脚本的跟踪,为网站增加流量..往好了用什么都能干,就是不能让一个网站下线。 FTP客户端Java类库 ftp4j ftp4j是一个FTP客户端Java类库,实现了FTP客户端应具有的大部分...

    java开源包6

    Port Groper可以与用测试防火墙,干扰web 统计脚本的跟踪,为网站增加流量..往好了用什么都能干,就是不能让一个网站下线。 FTP客户端Java类库 ftp4j ftp4j是一个FTP客户端Java类库,实现了FTP客户端应具有的大部分...

    java开源包5

    Port Groper可以与用测试防火墙,干扰web 统计脚本的跟踪,为网站增加流量..往好了用什么都能干,就是不能让一个网站下线。 FTP客户端Java类库 ftp4j ftp4j是一个FTP客户端Java类库,实现了FTP客户端应具有的大部分...

    java开源包10

    Port Groper可以与用测试防火墙,干扰web 统计脚本的跟踪,为网站增加流量..往好了用什么都能干,就是不能让一个网站下线。 FTP客户端Java类库 ftp4j ftp4j是一个FTP客户端Java类库,实现了FTP客户端应具有的大部分...

    java开源包4

    Port Groper可以与用测试防火墙,干扰web 统计脚本的跟踪,为网站增加流量..往好了用什么都能干,就是不能让一个网站下线。 FTP客户端Java类库 ftp4j ftp4j是一个FTP客户端Java类库,实现了FTP客户端应具有的大部分...

    java开源包8

    Port Groper可以与用测试防火墙,干扰web 统计脚本的跟踪,为网站增加流量..往好了用什么都能干,就是不能让一个网站下线。 FTP客户端Java类库 ftp4j ftp4j是一个FTP客户端Java类库,实现了FTP客户端应具有的大部分...

Global site tag (gtag.js) - Google Analytics