我有几个目录,其中的文件大多具有相同的名称,但可能不同,我需要将所有这些目录合并到一个新目录中。我需要能够比较相同的命名文件,如果相同则忽略/覆盖,或者如果不同则通过将修改日期/时间附加到文件名来移动/重命名旧文件。
要添加更多详细信息并解决@Serhat Cevikel 和@Wildcard:数据存储在具有相似结构的两个驱动器上,并且由于存在需要考虑的子文件夹,因此有点复杂。这是我创建的测试环境的树和一些评论:
/bmrlbackup/drive1/
`-- user001
`-- directory1
`-- project001
|-- file000 #identical
|-- file001 #older same name
|-- file0011 #unique
|-- phase1
| |-- file000 #identical
| |-- file110 #unique
| |-- file999 #newer same name
| `-- phase11
| `-- file111 #unique
`-- phase2
`-- file120 #unique
/bmrlbackup/drive2/
`-- user002
`-- directory2
`-- project001
|-- file000 #identical
|-- file001 #newer same name
|-- file0012 #unique
|-- phase1
| |-- file000 #identical
| |-- file210 #unique
| `-- file999 #older same name
`-- phase2
|-- file220 #unique
`-- phase21
`-- file221 #unique
第一个 rsync 的输出:
#rsync -a --ignore-existing --remove-source-files $sd1/ $dd1/
project001/
project001/file0011
project001/phase1/
project001/phase1/file110
project001/phase1/phase11/
project001/phase1/phase11/file111
project001/phase2/
project001/phase2/file120
更改了 remm(剩余的“相同”文件)以列出子目录:
#remm=`ls -1 $(find $sd1/ -type f)`
/bmrlbackup/drive1/user001/directory1/project001/file000
/bmrlbackup/drive1/user001/directory1/project001/file001
/bmrlbackup/drive1/user001/directory1/project001/phase1/file000
/bmrlbackup/drive1/user001/directory1/project001/phase1/file999
在这里,两个文件:
/bmrlbackup/drive1/user001/directory1/project001/file000
/bmrlbackup/drive1/user001/directory1/project001/phase1/file000
两个位置相同,无需复制或可以移动并覆盖目标。
同名不同内容文件:
/bmrlbackup/drive1/user001/directory1/project001/file001
/bmrlbackup/drive1/user001/directory1/project001/phase1/file999
需要比较“同名不同内容”文件,旧文件需要重命名:附加修改日期和时间,因此如果源较新,则附加目标文件的名称并移动源,如果源较旧,然后追加源的名称并移动名称追加的源。
此过程的结果最终会将所有文件从驱动器 1 移动到驱动器 2。
然后,oldest=`find {$sd1,$dd1} 的所有错误......
建议?
每个驱动器上的文件不超过10000个,大小从4k到800M。
答案1
如果我没记错的话,你的意思是,当文件名不同时 mv 文件,当文件名相同时,重命名旧文件,附加 mod 日期/时间,然后附加 mv。脚本如下:第一个参数是源路径,第二个参数是目标路径。您不应在路径末尾添加斜杠:
(更新:“ls”被“find”替换,有两个目的:不解析 ls,以及按日期对多个路径中的文件进行排序。变量替换本身更加简洁 通配符和空格和“:”都是替换为空格)
#!/bin/bash
sd1=$1
dd1=$2
rsync -a --ignore-existing --remove-source-files $sd1/ $dd1/
remm=`ls $sd1`
for i in $remm
do
oldest=`find {$sd1,$dd1} -type f -name $i -printf "%T@ %p\n" | sort -n | head -1 | cut -d " " -f2`
appendd=`stat $oldest --printf=%y\n | sed 's/ +.*//g' | sed 's/[ :]/_/g'`
newname="${oldest}_$appendd"
mv $oldest $newname
done
rsync -a --ignore-existing --remove-source-files $sd1/ $dd1/