我有三个目录。我想将directory1与directory2进行比较,然后获取这些更改/新文件并将它们复制到directory3。有没有一种简单的方法可以做到这一点,也许通过使用linux diff和cp命令?我对这些想法持开放态度。
谢谢!
安德鲁
答案 0 :(得分:1)
我相信这是你想要的描述。
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,那么你想要的是什么。
答案 1 :(得分:1)
线程yonder很好地解决了你的问题,我认为!
从那里复制:
#!/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
答案 2 :(得分:1)
您也可以在没有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命令中删除所有其他文本,然后复制保留目录结构的文件。
答案 3 :(得分:0)
之前发布的两个答案帮助我开始,但没有让我一路走来。 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
答案 4 :(得分:0)
考虑您在同一级别上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
然后你应该将你的差异更新为来自$BASEDIR
路径的dir2
的修剪
像这样
diff -ruN dir1 $BASEDIR/dir2 | \
perl -slne 'BEGIN {$base =~ s/\//\\\//g; print $base}
s/\+\+\+ $base\//\+\+\+ /g; print' \
-- -base=$BASEDIR
然后您可以应用上面生成的路径。