Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 比较2个目录并将差异复制到目录3_Linux_Comparison_Diff_Compare_Cp - Fatal编程技术网

Linux 比较2个目录并将差异复制到目录3

Linux 比较2个目录并将差异复制到目录3,linux,comparison,diff,compare,cp,Linux,Comparison,Diff,Compare,Cp,我有三个目录。我想比较directory1和directory2,然后将这些更改/新文件复制到directory3。有没有一种简单的方法可以做到这一点,也许可以使用LinuxDiff和cp命令?我乐于接受各种想法 谢谢 安德鲁我相信这就是你想从你的描述中得到的 for file in dir2/*; do file_in_dir1=dir1/$(basename ${file}) if [ ! -e ${file_in_dir1} ]; then # If th

我有三个目录。我想比较directory1和directory2,然后将这些更改/新文件复制到directory3。有没有一种简单的方法可以做到这一点,也许可以使用LinuxDiff和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

之前发布的两个答案帮助我开始了学习,但并没有让我一路走到那里。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
回波1>dir1/a
回波1>dir2/a
回声2>dir1/b
回声3>dir2/b
回声4>dir2/c
cp-r目录1目录3
创建并应用如下修补程序时:

diff-rundir1 dir2 | patch-p1-d dir3
然后就有了与之相当的
dir2
dir3
的内容

如果您的
dir2
dir1不在同一级别
然后您必须编辑修补程序中的文件名
这样就有了等量的路径组件
在
dir1
dir2
文件名中

您最好将
dir2
放在与
dir1
相同的级别, 因为没有一种优雅的方式可以做到这一点(至少我知道)

这里有一种“丑陋”的方式

假设您的
dir2
位于某些
$BASEDIR
然后您应该从
dir2
的路径更新diff以修剪
$BASEDIR
像这样

diff-运行dir1$BASEDIR/dir2|\
perl-slne'BEGIN{$base=~s/\/\\\//g;print$base}
s/\+\+$base\/\+\+/g;印刷品\
---base=$BASEDIR

然后您可以如上所述应用生成的路径。

您也可以在不使用bash脚本的情况下执行此操作:

diff-qr./dir1./dir2 | sed-e's/^仅在\(.*):\(.*)/\1\/\2/g'-e's/和\..*different$//g'-e's/^文件//g'-xargs-I'{}cp-Rf-父母{}./dir3/


此解决方案使用sed从diff命令中删除所有附加文本,然后复制保留目录结构的文件

您是想在shell脚本中执行此操作还是编写一些代码?我使用Total Commander的目录比较模式进行此操作,非常棒!TC是我在Linux.w3d上错过的唯一一个Windows程序:如果可以的话,我宁愿在shell脚本中完成。我希望有一种方法可以将LinuxDiff命令与LinuxCP命令一起使用。卡尔:我会查一查的,谢谢。。。