3

我有三个目录。我想将 directory1 与 directory2 进行比较,然后将这些更改/新文件复制到 directory3 中。有没有一种简单的方法可以做到这一点,也许是通过使用 linux diff 和 cp 命令?我对想法持开放态度。

谢谢!

安德鲁

4

5 回答 5

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,那么您想要什么。

于 2010-07-16T18:48:26.173 回答
1

我应该认为,那边的线程很好地解决了您的问题!

从那里复制:

#!/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
于 2010-07-16T18:55:39.970 回答
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 命令中删除所有附加文本,然后复制保留目录结构的文件。

于 2013-08-01T23:52:08.617 回答
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
于 2012-06-05T03:19:01.247 回答
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

然后你有内容dir2dir3等价物。

如果您dir2不在同一级别,dir1 那么您必须在补丁中编辑文件名,以便在文件名dir1dir2文件名中拥有相等数量的路径组件。

您最好将您dir2的级别设置为dir1,因为没有优雅的方法可以做到这一点(至少我知道)。

这里遵循一个“丑陋”的方式。

考虑您dir2的位置,$BASEDIR 那么您应该更新您的差异以修剪$BASEDIRfromdir2的路径,如下所示

    diff -ruN dir1 $BASEDIR/dir2 | \
    perl -slne 'BEGIN {$base =~ s/\//\\\//g; print $base}
                    s/\+\+\+ $base\//\+\+\+ /g; print'  \
    -- -base=$BASEDIR

然后你可以应用上面的结果路径。

于 2013-01-08T08:58:27.307 回答