文档章节

iOS使用Shell脚本批量修改类名称

aron1992
 aron1992
发布于 2018/03/01 18:40
字数 2922
阅读 6990
收藏 11

背景

公司需要做一系列的壳版本,壳版本如果内容雷同提交到App Store会有被拒绝的风险,在之前的两篇文章 iOS使用shell脚本注入混淆内容iOS使用shell脚本批量修改属性 中介绍了两种方式来绕过苹果后台的机器审查,这篇文章还是在这个业务场景中,介绍的是使用脚本批量重命名类名称,加强壳版本。

shell实战的系列文章
iOS使用shell脚本注入混淆内容
iOS使用Shell脚本批量修改类名称
iOS使用shell脚本批量修改属性

结果

使用方法

  • 打开测试工程

测试工程位于项目目录下面的DevPods/InjectedContentKit/Example/目录下,打开InjectedContentKit.xcworkspace即可

  • 执行命令

在命令行中进入到项目目录下面的DevPods/InjectedContentKit/Example/injectContentShell子目录,在我的电脑对应的目录为/Users/aron/git-repo/YTTInjectedContentKit/DevPods/InjectedContentKit/Example/injectContentShell,然后执行./RenameClasses.sh脚本文件批量修改类名

➜  injectContentShell git:(master) pwd
/Users/aron/git-repo/YTTInjectedContentKit/DevPods/InjectedContentKit/Example/injectContentShell
➜  injectContentShell git:(master) ./RenameClasses.sh 
目录存在 /Users/aron/git-repo/YTTInjectedContentKit/DevPods/InjectedContentKit/Example/injectContentShell/../injectedContentKit/Business
// .... 省略
new_file_path = /Users/aron/git-repo/YTTInjectedContentKit/DevPods/InjectedContentKit/Example/injectContentShell/../InjectedContentKit/Business/Pay/XYZSSCatchPayMethodSchedulerABC.m
批量重命名类名完成。

下面是执行脚本替换了类名的结果图,脚本把所有需要替换的类添加了XYZ前缀和ABC后缀,运行项目还是可以正常的编译运行的。如果遇到不正常、编译不通过或者崩溃的情况,一般的把出现问题的类写入到黑名单的配置文件中,以备下一次运行的脚本的时候把该问题的类排除。

本文的Demo代码YTTInjectedContentKit

类名称修改结果

修改之后的内容不要提交到版本管理系统,首先使用SVN或者GIT的discard功能丢弃修改,还需要执行DeleteClasses.sh脚本删除临时文件。

➜  injectContentShell git:(master) ✗ ./DeleteClasses.sh 
目录存在 /Users/aron/git-repo/YTTInjectedContentKit/DevPods/InjectedContentKit/Example/InjectedContentKit/Business
删除文件>>>/Users/aron/git-repo/YTTInjectedContentKit/DevPods/InjectedContentKit/Example/InjectedContentKit/Business/Pay/XYZSSCatchPayMethodSchedulerABC.h
删除文件>>>/Users/aron/git-repo/YTTInjectedContentKit/DevPods/InjectedContentKit/Example/InjectedContentKit/Business/Pay/XYZSSCatchPayMethodSchedulerABC.m
删除文件>>>/Users/aron/git-repo/YTTInjectedContentKit/DevPods/InjectedContentKit/Example/InjectedContentKit/Business/XYZSSCatchInviteSchedulerABC.h
删除文件>>>/Users/aron/git-repo/YTTInjectedContentKit/DevPods/InjectedContentKit/Example/InjectedContentKit/Business/XYZSSCatchInviteSchedulerABC.m

分析

原理分析

具体的原理分析可以查看我的这篇文章 iOS使用shell脚本批量修改属性,本质上都是通过修改符号来绕过苹果后台的机器审核

步骤分析

主要有以下几个步骤,和 iOS使用shell脚本批量修改属性 文章中的步骤很类似,有些细节的地方会有些差别而已

  1. 寻找到需要替换的源文件中的所有的类,处理之后保存在配置文件中
  2. 用户自定义一个黑名单配置文件
  3. 把需要替换的源文件中的所有匹配的类名信息做批量的替换
  4. 修改类源文件的名称

实现

单步实现

1. 寻找到需要替换的源文件中的所有的类,处理之后保存在配置文件中

这一步的功能是客户端指定一个需要处理的源码文件夹,递归遍历该源码文件夹获取所有源码文件。把找到的类名称暂时保存到数组中,最后经过黑名单过滤、去重过滤、其他过滤条件过滤,最终把待处理的类名保存到客户指定的输出文件中。

这部分功能的源码如下:
文件名: GetAndStoreClasses.sh

#!/bin/bash
########################
# 脚本功能:生成重命名的类的配置脚本
# 输入参数 -i 输入的文件夹
# 输入参数 -o 保存的文件
########################


####### 参数定义
param_input_dir=""
param_output_file=""


####### 参数解析
echo "参数>>${@}"
while getopts :i:o: opt
do
	case "$opt" in
		i) param_input_dir=$OPTARG
			echo "Found the -i option, with parameter value $OPTARG"
			;;
		o) param_output_file=$OPTARG
			echo "Found the -o option, with parameter value $OPTARG"
			;;
		*) echo "Unknown option: $opt";;
	esac
done
echo "param_input_dir = ${param_input_dir}"
echo "param_output_file = ${param_output_file}"


####### 配置

# 属性黑名单配置文件
blacklist_cfg_file="$(pwd)/DefaultClassesBlackListConfig.cfg"


####### 数据定义

# 定义保存需要处理目标文件的数组
declare -a implement_source_file_array
declare -a implement_source_file_name_array
implement_source_file_count=0

# mark: p384
# 递归函数读取目录下的所有.m文件
function read_implement_file_recursively {
	echo "read_implement_file_recursively"
	if [[ -d $1 ]]; then
		for item in $(ls $1); do
			itemPath="$1/${item}"
			if [[ -d $itemPath ]]; then
				# 目录
				echo "处理目录 ${itemPath}"
				read_implement_file_recursively $itemPath
				echo "处理目录结束====="
			else 
				# 文件
				echo "处理文件 ${itemPath}"
				if [[ $(expr "$item" : '.*\.m') -gt 0 ]]; then
					echo ">>>>>>>>>>>>mmmmmmm"
					implement_source_file_array[$implement_source_file_count]=${itemPath}
					class_name=${item//".m"/""};
					implement_source_file_name_array[$implement_source_file_count]=${class_name}
					implement_source_file_count=$[ implement_source_file_count + 1 ];
				fi
				echo ""
			fi
		done
	else
		echo "err:不是一个目录"
	fi
}

post_implement_file_handle() {
	local wirte_to_file=$1
	# 写入文件中
	echo "# 需要处理的类配置文件" > ${wirte_to_file}
	for(( i=0;i<${#implement_source_file_name_array[@]};i++)) 
	do 
		class_file_name=${implement_source_file_name_array[i]}; 
		echo ${class_file_name} >> ${wirte_to_file}
	done;

	# 去重
	wirte_to_file_bak="${wirte_to_file}.bak"
	mv ${wirte_to_file} ${wirte_to_file_bak}
	sort ${wirte_to_file_bak} | uniq > ${wirte_to_file}

	# 过滤
	mv ${wirte_to_file} ${wirte_to_file_bak}
	echo "# Properties Configs Filtered" > ${wirte_to_file}
	IFS_OLD=$IFS
	IFS=$'\n'
	# 上一行的内容
	lastLine="";
	for line in $(cat ${wirte_to_file_bak} | sed 's/^[ \t]*//g')
	do
		grep_result=$(grep ${line} ${blacklist_cfg_file})
		category_judge_substring="\+"
		if [[ ${#line} -le 6 ]] || [[ $(expr "$line" : '^#.*') -gt 0 ]] || [[ -n ${grep_result} ]] || [[ ${line} =~ ${category_judge_substring} ]]; then
			# 长度小于等于6、注释内容的行、在黑名单中的内容、分类文件不处理
			echo "less then 6 char line or comment line"
		else
			if [[ -n ${lastLine} ]]; then
				# 上一行是非空白行
				# 比较上一行内容是否是当前行的一部分,不是添加上一行
				if [[ ${line} =~ ${lastLine} ]]; then
					echo "${line} 和 ${lastLine} 有交集"
				else
					echo ${lastLine} >> ${wirte_to_file}
				fi
			fi
			# 更新上一行
			lastLine=${line}
		fi	
	done
	IFS=${IFS_OLD}

	# 删除临时文件
	rm -f ${wirte_to_file_bak}
}

read_implement_file_recursively ${param_input_dir}
post_implement_file_handle ${param_output_file}


使用以上脚本生成的配置文件 RenameClasses.cfg 部分如下:

# Properties Configs Filtered
AppDelegate
CatchRecordViewController
SSCatchAboutUsScheduler
SSCatchAccountHandler
SSCatchActivityManager
SSCatchActivityScheduler
SSCatchAddressListOrganizer
SSCatchAddressListScheduler

2. 用户自定义一个黑名单配置文件

在实践的过程中,有些类文件的归属不明确,比如属于业务的类文件有部分放到了技术分类的文件夹下,这样对业务的类文件是有依赖的,而重命名类的时候不会对这部分类文件进行操作,而他所依赖的业务类文件发生了变化,就会出现编译错误的情况。对于这类问题,一种方法是去调整类位置,或者还需要进行一些重构,比较麻烦;另一种简单的方法是黑名单中配置一些默认的过滤项目,对于黑名单中的这些项目不处理即可,在我的业务场景下,黑名单文件的配置如下:

文件名:DefaultClassesBlackListConfig.cfg

# DefaultClassesBlackListConfig.cfg
SSCatchRequest
SSCatchCouponSampler
SSCatchRoomRecordTiler
SSCatchColorFormatter

3. 把需要替换的源文件中的所有匹配的类名信息做批量的替换

这一步在前面两部的基础上,查找并替换源码目录中在 RenameClasses.cfg 配置文件中出现的类和类引用,查找使用grep命令、替换使用了sed命令。脚本代码如下

# 2、根据规则修改类名
function add_prefix_suffix_to_class {
	# 2.1、类添加前缀和后缀
	for (( i = 0; i < ${#config_content_array[@]}; i++ )); do
		original_class_name=${config_content_array[i]};
		result_class_name="${class_prefix}${original_class_name}${class_suffix}"

		sed -i '{
			s/'"${original_class_name}"'/'"${result_class_name}"'/g
		}' `grep ${original_class_name} -rl ${pbxproj_dir}`
		sed -i '{
			s/'"${original_class_name}"'/'"${result_class_name}"'/g
		}' `grep ${original_class_name} -rl ${class_name_replace_dir}`

		sed -i '{
			s/'"${original_class_name}"'/'"${result_class_name}"'/g
		}' `grep ${original_class_name} -rl ${class_name_replace_support_dir}`

		echo "正在处理类 ${original_class_name}..."
	done
}

4. 修改类源文件的名称

使用 mv 命令重命名在 RenameClasses.cfg 配置文件中出现的类

# 3、修改类的文件名称
function rename_class_file {
	echo "class_name_replace_dir >> ${class_name_replace_dir}"
	for (( i = 0; i < ${#config_content_array[@]}; i++ )); do
		
		original_class_name=${config_content_array[i]};
		result_class_name="${class_prefix}${original_class_name}${class_suffix}"

		# .h 文件
		pattern="${original_class_name}\.h"
		find_result=$(find ${class_name_replace_dir} -name ${pattern})
		new_file_path=${find_result/$original_class_name/$result_class_name}
		echo "find_result = ${find_result}"
		echo "new_file_path = ${new_file_path}"
		mv -f $find_result $new_file_path

		# .m 文件
		pattern="${original_class_name}\.m"
		find_result=$(find ${class_name_replace_dir} -name ${pattern})
		new_file_path=${find_result/$original_class_name/$result_class_name}
		echo "find_result = ${find_result}"
		echo "new_file_path = ${new_file_path}"
		mv -f $find_result $new_file_path

	done
}

完整重命名类的脚本

#!/bin/bash
########################
# 脚本功能:类重命名脚本
# 输入参数 -i 输入的文件夹
# 输入参数 -o 保存的文件
########################


####### 配置
# 定义需要替换的类的查找目录,作为参数传递给GenRenameClasses.sh脚本使用,最终获取到的类名称保存到配置文件中,以给后续步骤使用
class_search_dir="$(pwd)/../injectedContentKit/Business000"
# class_search_dir="$(pwd)/../injectedContentKit/Business"
class_search_dir="/Users/aron/PuTaoWorkSpace/project/sscatch/sscatch/Classes/Business"
# 配置文件
cfg_file="$(pwd)/RenameClasses.cfg"

# project.pbxproj文件目录,需要替换该配置文件中的类的名称配置
pbxproj_dir="$(pwd)/../InjectedContentKit.xcodeproj000"
# pbxproj_dir="$(pwd)/../InjectedContentKit.xcodeproj"
pbxproj_dir="/Users/aron/PuTaoWorkSpace/project/sscatch/sscatch.xcodeproj"

# 定义该目录下的文件需要进行批量替换处理
class_name_replace_dir="$(pwd)/../InjectedContentKit000"
# class_name_replace_dir="$(pwd)/../InjectedContentKit"
class_name_replace_dir="/Users/aron/PuTaoWorkSpace/project/sscatch/sscatch/Classes/Business"

# 定义该目录下的文件需要进行批量替换处理
class_name_replace_support_dir="$(pwd)/../InjectedContentKit000"
# class_name_replace_support_dir="$(pwd)/../InjectedContentKit"
class_name_replace_support_dir="/Users/aron/PuTaoWorkSpace/project/sscatch/sscatch/SupportingFiles"


# 类前缀
class_prefix="XYZ"
# 类后缀
class_suffix="ABC"


####### 配置检查处理

# 导入工具脚本
. ./FileUtil.sh

# 检测 class_search_dir
checkDirCore $class_search_dir "指定类的查找目录不存在"
class_search_dir=${CheckInputDestDirRecursiveReturnValue} 

# 检测 pbxproj_dir
checkDirCore $pbxproj_dir "指定项目配置目录(pbxproj所在的目录,一般是 xxx.xcodeproj)不存在"
pbxproj_dir=${CheckInputDestDirRecursiveReturnValue}

# 检测 class_name_replace_dir
checkDirCore $class_name_replace_dir "指定类名称修改的目录不存在"
class_name_replace_dir=${CheckInputDestDirRecursiveReturnValue}

# 检测 class_name_replace_support_dir
checkDirCore $class_name_replace_support_dir "指定类名称修改的目录不存在"
class_name_replace_support_dir=${CheckInputDestDirRecursiveReturnValue}


# 检测或者创建配置文件
checkOrCreateFile $cfg_file


####### 数据定义
# 定义保存类名称的数组
declare -a config_content_array
cfg_line_count=0

# 1、读取配置文件内容保存到数组中
read_config_content_to_array() {
	# 读取配置文件
	echo "开始读取配置文件..."
	# mark: p291
	IFS_OLD=$IFS
	IFS=$'\n'
	# 删除文件行首的空白字符 http://www.jb51.net/article/57972.htm
	for line in $(cat $cfg_file | sed 's/^[ \t]*//g')
	do
		is_comment=$(expr "$line" : '^#.*')
		echo "line=${line} is_common=${is_comment}"
		if [[ ${#line} -eq 0 ]] || [[ $(expr "$line" : '^#.*') -gt 0 ]]; then
			echo "blank line or comment line"
		else
			config_content_array[$cfg_line_count]=$line
			cfg_line_count=$[ $cfg_line_count + 1 ]
			echo "line>>>>${line}"
		fi	
	done
	IFS=${IFS_OLD}

	for (( i = 0; i < ${#config_content_array[@]}; i++ )); do
		config_content=${config_content_array[i]};
		echo "config_content>>>>>>${config_content}"
	done
}


# 2、根据规则修改类名
function add_prefix_suffix_to_class {
	# 2.1、类添加前缀和后缀
	for (( i = 0; i < ${#config_content_array[@]}; i++ )); do
		original_class_name=${config_content_array[i]};
		result_class_name="${class_prefix}${original_class_name}${class_suffix}"

		sed -i '{
			s/'"${original_class_name}"'/'"${result_class_name}"'/g
		}' `grep ${original_class_name} -rl ${pbxproj_dir}`
		sed -i '{
			s/'"${original_class_name}"'/'"${result_class_name}"'/g
		}' `grep ${original_class_name} -rl ${class_name_replace_dir}`

		sed -i '{
			s/'"${original_class_name}"'/'"${result_class_name}"'/g
		}' `grep ${original_class_name} -rl ${class_name_replace_support_dir}`

		echo "正在处理类 ${original_class_name}..."
	done
}

# 3、修改类的文件名称
function rename_class_file {
	echo "class_name_replace_dir >> ${class_name_replace_dir}"
	for (( i = 0; i < ${#config_content_array[@]}; i++ )); do
		
		original_class_name=${config_content_array[i]};
		result_class_name="${class_prefix}${original_class_name}${class_suffix}"

		# .h 文件
		pattern="${original_class_name}\.h"
		find_result=$(find ${class_name_replace_dir} -name ${pattern})
		new_file_path=${find_result/$original_class_name/$result_class_name}
		echo "find_result = ${find_result}"
		echo "new_file_path = ${new_file_path}"
		mv -f $find_result $new_file_path

		# .m 文件
		pattern="${original_class_name}\.m"
		find_result=$(find ${class_name_replace_dir} -name ${pattern})
		new_file_path=${find_result/$original_class_name/$result_class_name}
		echo "find_result = ${find_result}"
		echo "new_file_path = ${new_file_path}"
		mv -f $find_result $new_file_path

	done
}

# 获取需要重命名的类名称,保存到配置文件中
./GetAndStoreClasses.sh\
	-i ${class_search_dir}\
	-o ${cfg_file}

# 读取配置文件内容保存到数组中
read_config_content_to_array
# 类名以及引用添加前缀和后缀
add_prefix_suffix_to_class
# 修改类文件名字
rename_class_file

echo "批量重命名类名完成。"

删除重命名后的类文件

这里有个需要注意的地方是不要把重命名后的类提交到SVN或者Git,使用完了之后使用Revert功能回滚代码即可,因为提交了之后你的配置文件会失效,需要重新整理。我们公司使用的是SVN,revert操作之后重命名之后的文件不会revert,所以有了这个脚本,批量删除重命名之后的文件。

#!/bin/bash
########################
# 脚本功能:删除类重命名脚本产生生成的类
########################

####### 配置
# 定义需要替换的类的查找目录,作为参数传递给GenRenameClasses.sh脚本使用,最终获取到的类名称保存到配置文件中,以给后续步骤使用
class_search_dir="$(pwd)/../injectedContentKit/Business000"
class_search_dir="/Users/aron/PuTaoWorkSpace/project/sscatch/sscatch/Classes/Business"

# 类前缀
class_prefix="XYZ"
# 类后缀
class_suffix="ABC"


####### 配置检查处理
# 导入工具脚本
. ./FileUtil.sh

# 检测 class_search_dir
checkDirCore $class_search_dir "指定类的查找目录不存在"
class_search_dir=${CheckInputDestDirRecursiveReturnValue} 

# 也可以使用$(grep -rl "XYZ.*ABC" ${class_search_dir})
for class_file_path in `grep -rl "XYZ.*ABC" ${class_search_dir}`; do
	echo "删除文件>>>${class_file_path}"
	rm -f ${class_file_path}
done

总结

以上就是基于Shell脚本,以壳版本为场景,把类的批量替换做了一个半自动化的实现步骤,如果不妥之处,还请不吝赐教。

© 著作权归作者所有

aron1992

aron1992

粉丝 65
博文 90
码字总数 164172
作品 0
厦门
程序员
私信 提问
加载中

评论(17)

songbai1211
songbai1211
Trying to install gun sed...
Error: No available formula with the name "gnu-sed@4.4"
==> Searching for a previously deleted formula (in the last month)...
Warning: homebrew/core is shallow clone. To get complete history run:
git -C "$(brew --repo homebrew/core)" fetch --unshallow

Error: No previously deleted formula found.
==> Searching for similarly named formulae...
Error: No similarly named formulae found.
==> Searching taps...
==> Searching taps on GitHub...
Error: No formulae found in taps.
抱这个错误,大神什么情况,求帮忙看下
songbai1211
songbai1211
➜ injectContentShell git:(master) ./RenameClasses.sh
目录存在 /Users/zhangsongbai/Desktop/代码混淆/YTTInjectedContentKit/DevPods/InjectedContentKit/Example/injectContentShell/../injectedContentKit/Business
目录存在 /Users/zhangsongbai/Desktop/代码混淆/YTTInjectedContentKit/DevPods/InjectedContentKit/Example/injectContentShell/../InjectedContentKit.xcodeproj
目录存在 /Users/zhangsongbai/Desktop/代码混淆/YTTInjectedContentKit/DevPods/InjectedContentKit/Example/injectContentShell/../InjectedContentKit
检测到文件存在 /Users/zhangsongbai/Desktop/代码混淆/YTTInjectedContentKit/DevPods/InjectedContentKit/Example/injectContentShell/configures/RenameClasses.cfg
/usr/bin/sed
testresult = 0
-rwxr-xr-x 1 root wheel 42176 10 26 2017 /usr/bin/sed
testresult = 0
Trying to install gun sed...
Error: No available formula with the name "gnu-sed@4.4"
==> Searching for a previously deleted formula (in the last month)...
Warning: homebrew/core is shallow clone. To get complete history run:
git -C "$(brew --repo homebrew/core)" fetch --uns
SL-Feng
SL-Feng

引用来自“SL-Feng”的评论

你好,脚本里面的配置好像存在一个问题,就是如果A的名字和B的名字相差几个字母的话,会有一个没有被更改成功,但是如果将if [[ -n ${lastLine} ]]; then
        # 上一行是非空白行
        # 比较上一行内容是否是当前行的一部分,不是添加上一行
        # if [[ ${line} =~ ${lastLine} ]]; then
        #   echo "${line} 和 ${lastLine} 有交集"
        # else
        #   echo ${lastLine} >> ${wirte_to_file}
        # fi
        #无论有没有交集,全部都更改
        echo ${lastLine} >> ${wirte_to_file}的话,那么是全部更改了,但是会存在错误现象,说明一下假如有一个View是TestView,Controller是TestViewController的话,那么我将前缀设置为AB的时候,执行脚本之后,会出现View时ABTestView,但是controller会变成ABABTestViewController,但是实际在目录中存在的是ABTestViewController,项目变异会报错,看了你脚本,好像也没有什么问题,但是就是会出现这个怪异现象,希望作者可以尝试一下看看

引用来自“aron1992”的评论

当时是因为会出现名字是另一个一部分导致出错添加了这个处理逻辑的,因为ABTestViewController同时参与了ABTestView和ABTestViewController的修改规则,就是修改了两次

引用来自“SL-Feng”的评论

出现这样的结果,应该是ABTestViewController会执行两次,但是执行脚本的时候,却发现更改类名的方法只是执行一次,所以你说的那个ABTestViewController执行两次,具体体现在那一段呢?
原来是sed导致的,目前就只能通过判断去掉?有没有更改的方法呢
SL-Feng
SL-Feng

引用来自“SL-Feng”的评论

你好,脚本里面的配置好像存在一个问题,就是如果A的名字和B的名字相差几个字母的话,会有一个没有被更改成功,但是如果将if [[ -n ${lastLine} ]]; then
        # 上一行是非空白行
        # 比较上一行内容是否是当前行的一部分,不是添加上一行
        # if [[ ${line} =~ ${lastLine} ]]; then
        #   echo "${line} 和 ${lastLine} 有交集"
        # else
        #   echo ${lastLine} >> ${wirte_to_file}
        # fi
        #无论有没有交集,全部都更改
        echo ${lastLine} >> ${wirte_to_file}的话,那么是全部更改了,但是会存在错误现象,说明一下假如有一个View是TestView,Controller是TestViewController的话,那么我将前缀设置为AB的时候,执行脚本之后,会出现View时ABTestView,但是controller会变成ABABTestViewController,但是实际在目录中存在的是ABTestViewController,项目变异会报错,看了你脚本,好像也没有什么问题,但是就是会出现这个怪异现象,希望作者可以尝试一下看看

引用来自“aron1992”的评论

当时是因为会出现名字是另一个一部分导致出错添加了这个处理逻辑的,因为ABTestViewController同时参与了ABTestView和ABTestViewController的修改规则,就是修改了两次
出现这样的结果,应该是ABTestViewController会执行两次,但是执行脚本的时候,却发现更改类名的方法只是执行一次,所以你说的那个ABTestViewController执行两次,具体体现在那一段呢?
aron1992
aron1992 博主

引用来自“SL-Feng”的评论

你好,脚本里面的配置好像存在一个问题,就是如果A的名字和B的名字相差几个字母的话,会有一个没有被更改成功,但是如果将if [[ -n ${lastLine} ]]; then
        # 上一行是非空白行
        # 比较上一行内容是否是当前行的一部分,不是添加上一行
        # if [[ ${line} =~ ${lastLine} ]]; then
        #   echo "${line} 和 ${lastLine} 有交集"
        # else
        #   echo ${lastLine} >> ${wirte_to_file}
        # fi
        #无论有没有交集,全部都更改
        echo ${lastLine} >> ${wirte_to_file}的话,那么是全部更改了,但是会存在错误现象,说明一下假如有一个View是TestView,Controller是TestViewController的话,那么我将前缀设置为AB的时候,执行脚本之后,会出现View时ABTestView,但是controller会变成ABABTestViewController,但是实际在目录中存在的是ABTestViewController,项目变异会报错,看了你脚本,好像也没有什么问题,但是就是会出现这个怪异现象,希望作者可以尝试一下看看
当时是因为会出现名字是另一个一部分导致出错添加了这个处理逻辑的,因为ABTestViewController同时参与了ABTestView和ABTestViewController的修改规则,就是修改了两次
SL-Feng
SL-Feng
你好,脚本里面的配置好像存在一个问题,就是如果A的名字和B的名字相差几个字母的话,会有一个没有被更改成功,但是如果将if [[ -n ${lastLine} ]]; then
        # 上一行是非空白行
        # 比较上一行内容是否是当前行的一部分,不是添加上一行
        # if [[ ${line} =~ ${lastLine} ]]; then
        #   echo "${line} 和 ${lastLine} 有交集"
        # else
        #   echo ${lastLine} >> ${wirte_to_file}
        # fi
        #无论有没有交集,全部都更改
        echo ${lastLine} >> ${wirte_to_file}的话,那么是全部更改了,但是会存在错误现象,说明一下假如有一个View是TestView,Controller是TestViewController的话,那么我将前缀设置为AB的时候,执行脚本之后,会出现View时ABTestView,但是controller会变成ABABTestViewController,但是实际在目录中存在的是ABTestViewController,项目变异会报错,看了你脚本,好像也没有什么问题,但是就是会出现这个怪异现象,希望作者可以尝试一下看看
纯情小飞飞
纯情小飞飞

引用来自“纯情小飞飞”的评论

你好 我用在自己项目中 在RenameClasses.sh 我将类名前缀和后缀改掉了 但是运行之后项目中类名并不是按照我设置的前缀和后缀改的 是什么情况呢?

引用来自“aron1992”的评论

后面改成随机的前缀了,你需要把代码中的两行注释就行了
在后面的代码里面 楼主设置的是随机字符串 你修改一下就对了 同一个文件118和119行位置
纯情小飞飞
纯情小飞飞

引用来自“纯情小飞飞”的评论

你好 我用在自己项目中 在RenameClasses.sh 我将类名前缀和后缀改掉了 但是运行之后项目中类名并不是按照我设置的前缀和后缀改的 是什么情况呢?
找到了 在下面设置了使用随机字符串 谢谢楼主
aron1992
aron1992 博主

引用来自“纯情小飞飞”的评论

你好 我用在自己项目中 在RenameClasses.sh 我将类名前缀和后缀改掉了 但是运行之后项目中类名并不是按照我设置的前缀和后缀改的 是什么情况呢?
后面改成随机的前缀了,你需要把代码中的两行注释就行了
纯情小飞飞
纯情小飞飞
你好 我用在自己项目中 在RenameClasses.sh 我将类名前缀和后缀改掉了 但是运行之后项目中类名并不是按照我设置的前缀和后缀改的 是什么情况呢?
Dhar/YTTInjectedContentKit

YTTInjectedContentKit iOS壳版本场景下的批量修改类名、属性名、插入混淆代码、修改项目名称的shell脚本 具体的实现和使用方法请参考我的博客文章: iOS使用shell脚本注入混淆内容 iOS使用S...

Dhar
2018/05/04
0
0
iOS音视频—FFmepg:iOS平台下集成和应用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wtdask/article/details/83901924 1.在iOS平台下集成和应用FFmpeg Mac配置FFmpeg环境 1、安装homebrew 2、安装...

十二指环
2018/11/12
0
0
Unity3D 游戏引擎之IOS高级界面发送消息与Unity3D消息的接收(九)

Unity3D 游戏引擎之IOS高级界面发送消息与Unity3D消息的接收 雨松MOMO原创文章如转载,请注明:转载自雨松MOMO的博客原文地址:http://blog.csdn.net/xys289187120/article/details/6926746 ...

彭博
2012/03/09
770
0
最简单的基于FFmpeg的移动端例子:Android HelloWorld

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/leixiaohua1020/article/details/47008825 ===================================================== 最简单的...

雷霄骅
2015/07/23
0
0
iOS使用Objective-c自定义cordova插件(-)

本系列教程为博主初次使用开发,内容如有差错,欢迎指正,敬请谅解。 博客地址:http://blog.img421.com/iosshi-yong-object-czi-ding-yi-cordovacha-jian/ Mac安装ionic和cordova我们已经熟悉,...

Michaelyn
2017/10/23
0
0

没有更多内容

加载失败,请刷新页面

加载更多

日志相关---日志配置和过滤器

一、log4j日志简介 1.1、 Loggers 级别和介绍 Loggers组件在此系统中被分为八个级别:ALL、TRANCE、DEBUG、INFO、WARN、ERROR和FATAL、OFF。这八个级别是有顺序的, ##off表示关闭ALL < T...

spinachgit
24分钟前
1
0
六个面试题层层剖析——LongAddr原子类

并发编程面试题 (1)LongAddr的结构是怎样的? (2)当前线程应该访问Cell数组里面的哪一个Cell元素? (3)如何初始化Cell数组? (4)Cell数组如何扩容? (5)线程访问分配的Cell元素有冲...

须臾之余
26分钟前
8
0
MySQL-入门(二)

本部分主要是MySQL的常用函数和高级用法。 一、MySQL排序 排序关键字:order by 排序字段。后面写上要排序字段,排序字段可以有多个,多个采用逗号间隔,order by默认采用升序(asc)排序,可...

潜行-L
36分钟前
3
0
BAM转VCF的方法对比

1 使用GATK HaplotypeCaller #java -jar gatk.jar HaplotypeCaller --native-pair-hmm-threads 4 -R xx.fa -I xx.bam -O xx.vcf --native-pair-hmm-threads用来设置多线程,默认为4线程 2 sa......

悲催的古灵武士
45分钟前
2
0
软件架构设计原则之“KISS”的总结使用

今天聊一聊软件架构设计中的 KISS 原则。 对! 就是亲嘴的那个 “KISS”! 一定要多练习。 ... ... ... ... 作为一个程序员我是推荐理解为“亲嘴”的,可以很好的解决单身问题,但作为一个架...

Owen_Jia
47分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部