我有三个目录。 我想比较directory1和directory2,然后把这些更改/新的文件,并复制到目录3。 有没有一种简单的方法来做到这一点,也许通过使用linux diff和cp命令? 我对想法持开放态度。
谢谢!
安德鲁
我相信这是你想要从你的描述。
for file in dir2/*; do file_in_dir1=dir1/$(basename ${file}) if [ ! -e ${file_in_dir1} ]; then # If the file in dir2 does not exist in dir1, copy cp ${file} dir3 elif ! diff ${file} ${file_in_dir1}; then # if the file in dir2 is different then the one in dir1, copy cp ${file} dir3 fi done
有一件事我不确定的是,如果一个文件存在于dir1而不是dir2中,你想要什么。
那个线程很好地解决你的问题,我应该想!
从那里复制:
#!/bin/bash # setup folders for our different stages DIST=/var/www/localhost/htdocs/dist/ DIST_OLD=/var/www/localhost/htdocs/dist_old/ DIST_UPGRADE=/var/www/localhost/htdocs/dist_upgrade/ cd $DIST list=`find . -type f` for a in $list; do if [ ! -f "$DIST_OLD$a" ]; then cp --parents $a $DIST_UPGRADE continue fi diff $a $DIST_OLD$a > /dev/null if [[ "$?" == "1" ]]; then # File exists but is different so copy changed file cp --parents $a $DIST_UPGRADE fi done
你也可以在没有bash脚本的情况下做到这一点:
diff -qr ./dir1 ./dir2 | sed -e 's/^Only in\(.*\): \(.*\)/\1\/\2/g' -e 's/ and \..*differ$//g' -e 's/^Files //g' | xargs -I '{}' cp -Rf --parents '{}' ./dir3/
此解决方案使用sed从diff命令中删除所有其他文本,然后复制保留目录结构的文件。
这两个以前发布的答案帮助我开始,但没有让我一直在那里。 thomax公布的解决方案非常接近,但遇到了osx上的cp命令不支持–parents参数的问题,所以我必须添加一些关于创建子文件夹的逻辑,这使得事情有点混乱,重组一下。 以下是我所结束的:
#!/bin/bash # setup folders for our different stages DIST=/var/www/localhost/htdocs/dist/ DIST_OLD=/var/www/localhost/htdocs/dist_old/ DIST_UPGRADE=/var/www/localhost/htdocs/dist_upgrade/ cd $DIST find . -type f | while read filename do newfile=false modified=false if [ ! -e "$DIST_OLD$filename" ]; then newfile=true echo "ADD $filename" elif ! cmp $filename $DIST_OLD$filename &>/dev/null; then modified=true echo "MOD $filename" fi if $newfile || $modified; then #massage the filepath to not include leading ./ filepath=$DIST_UPGRADE$(echo $filename | cut -c3-) #create folder for it if it doesnt exist destfolder=$(echo $filepath | sed -e 's/\/[^\/]*$/\//') mkdir -p $destfolder #copy new/modified file to the upgrade folder cp $filename $filepath fi done
考虑你有dir1
, dir2
和dir3
在同一级别的内容设置如下:
mkdir dir1 mkdir dir2 echo 1 > dir1/a echo 1 > dir2/a echo 2 > dir1/b echo 3 > dir2/b echo 4 > dir2/c cp -r dir1 dir3
当你像这样创建和应用补丁:
diff -ruN dir1 dir2 | patch -p1 -d dir3
然后你有相当于dir2
和dir3
内容。
如果您的dir2
与dir1
不在同一级别,那么您必须在该补丁中编辑文件名,以便在dir1
和dir2
文件名中都有相同数量的路径组件。
你最好把你的dir2
和dir1
放在同一个层次上,因为没有优雅的方法去做(至少我知道)。
这里遵循一个“丑陋”的方式。
考虑你的dir2
位于一些$BASEDIR
那么你应该更新你的差异修剪从这样的dir2
路径的$BASEDIR
这样
diff -ruN dir1 $BASEDIR/dir2 | \ perl -slne 'BEGIN {$base =~ s/\//\\\//g; print $base} s/\+\+\+ $base\//\+\+\+ /g; print' \ -- -base=$BASEDIR
然后你可以像上面那样应用结果路径。