背景
在日常工作当中,偶尔会遇到需要修改文件夹名字,修改文件名字以及修改文件内容的情况;当修改的关键字为固定内容的时候,且数量很多时,如果用人工手动修改,会非常耗时且乏味无趣。
下列脚本为了解决这个问题提供了思路和实践。个人经验所学,实际使用可能会有一些问题,欢迎指教;脚本请按需采用。
例如:
- 将文件内容 cont 修改为 content
- 将文件名 file_xxx.c 修改为 files_xxx.c
- 将文件夹 dir1 修改为 direct1
脚本说明
修改文件内容
grep -rl ${key} --include="*.c" --exclude="*.bin" --exclude-dir=“tool” | xargs sed -i "s/${key}/${value}/g"
grep -rl ${key} --include="*.c" --exclude="*.bin" --exclude-dir=“tool”
提取关键字为 ${key} 的文件相对路径名,该文件路径的后缀为 .c,但是后缀不为 .bin,该文件的路径不能为 tool。
xargs sed -i "s/${key}/${value}/g"
替换文件中 ${key} 关键字为 ${value},文件为前一条命令中的内容。MAC 系统下 sed -i 后面要接空格 “”,具体说明可搜索一下。
修改文件名
find . -name "*${key}*" -type f | sed -e "p;s/${key}/${value}/g" | xargs -n2 mv
find . -name "*${key}" -type f
找到一个文件,该文件名包含关键字 ${key}
修改文件夹名
find . -name "*${key}*" -type d | sed -e "p;s/${key}/${value}/g" | xargs -n2 mv
找到一个文件夹,该文件夹名包含关键字 ${key}
脚本示例
#/bin/bash
# define array
dirs=(
"demo"
"demo2"
)
# define a associate array,must in bash version 4
declare -A dic
dic=(
[cont]="replace"
[cont2]="replace2"
)
for dir in "${dirs[@]}"; do
if [ -d "${dir}/" ]; then
echo "${dir}"
cd ${dir}
for key in $(echo ${!dic[*]}); do
value=${dic[${key}]}
echo "${key} ==> ${value}"
# 1.修改文件内容
grep -rl ${key} --exclude="*.bin" --exclude-dir="tool" | xargs sed -i "" "s/${key}/${value}/g"
# 3.修改文件夹名
find . -name "*${key}*" -type d | sed -e "p;s/${key}/${value}/g" | xargs -n2 mv
# 2.修改文件名
find . -name "*${key}*" -type f | sed -e "p;s/${key}/${value}/g" | xargs -n2 mv
done
cd -
else
echo "dir not exist!"
fi
done
问题
当替换的关键字内容有重复时,比如用 cont 替换 content,此时会由于内容重叠导致出现一些重复替换或无法替换的问题,请注意。