一、情景描述
文件夹from:
test_from/
├── a1
│ └── a2
│ └── a # 文件a
└── c1
└── c2
└── c # 文件c
文件夹to:
test_to/
├── a1
│ └── a2
│ └── a # 文件a
└── b1
└── b2
└── b # 文件b
我们的目标是将from文件夹里不同于to文件夹里的文件内容拷贝到to中,即求from∪to
,最终文件夹to里的内容为:
test_to/
├── a1
│ └── a2
│ └── a
├── b1
│ └── b2
│ └── b
└── c1
└── c2
└── c
如果使用cp命令直接拷贝文件夹,如下所示,则需要我们不停的确定是否覆盖同名的文件,在文件数量巨大的情况下,这种方法将不可取。
[root@localhost marge]# cp -r test_from/* test_to/
cp: overwrite ‘test_to/a1/a2/a’?
为了解决这个问题,需要手写一个shell脚本,将文件夹to中已存在的同名同相对路径文件过滤掉,只将文件夹from中独有的文件拷贝到文件夹to中。
二、解决方案
为了方便起见,在文件夹from目录下创建我们的脚本myCp.sh
,创建后的文件结构如下:
test_from/
├── a1
│ └── a2
│ └── a
├── c1
│ └── c2
│ └── c
└── myCp.sh # 自定义脚本
下面是重点,myCp
中的内容:
# 函数参数:$1:目标文件夹绝对路径 $2:文件相对路径
function getTarget(){
prefix=$1
file=$2
# 1
# echo "debug ${prefix}"
# echo "debug ${file}"
for subfile in ${file}/*
do
# 2
# echo "debug subfile:${subfile}"
if test -f $subfile
then
# 判断是否是该脚本
if [ "./$0" == ${subfile} ]; then
continue
fi
targetFile=${prefix}${subfile:2}
# 3
#echo "debug ${targetFile}"
if [ ! -f ${targetFile} ]; then
echo "INFO cp ${subfile} ${targetFile}"
targetFileDir=${targetFile%/*}
# 4
# echo "debug ${targetFileDir}"
# 如果目标文件夹不存在则创建
if [ ! -d ${targetFileDir} ];then
mkdir -p ${targetFileDir}
fi
cp ${subfile} ${targetFile}
fi
else
# 5
# echo "debug ${prefix} ${subfile}"
getTarget ${prefix} ${subfile}
fi
done
}
if [ ! $1 ]; then
echo 'error: target file real path is null!'
exit 1
fi
prefix="$(realpath $1)/"
getTarget ${prefix} "."
看不懂脚本没关系,知道怎么用就可以。使用方法很简单:
[root@localhost test_from]# sh myCp.sh ../test_to/
INFO cp ./c1/c2/c /data/xxxx/xxxx/test_to/c1/c2/c
注意在运行的脚本后面加上目标文件夹(本案例中是文件夹to)的相对或绝对路径。
运行结果:
test_to/
├── a1
│ └── a2
│ └── a
├── b1
│ └── b2
│ └── b
└── c1
└── c2
└── c