Bash脚本将两个目录中的差异复制到第三个目录?

时间:2013-11-16 05:14:32

标签: bash shell

我想要做的是比较两个目录d1和d2,并复制d1和d2中不存在的所有文件。 d2到第三个目录,d3。

我知道我可以使用以下方法复制两个目录中的所有文件:

  

cp -vfudp dir1 / * dir3 /

     

cp -vfudp dir2 / * dir3 /

但我知道我需要合并find函数并进行比较。或差异。我可以用

吗?
  

rsync -a dir1 / dir2 /

以某种方式创建第三个目录并放置差异?

我想我需要使用

  

diff -r --brief dir1 dir2

也在那里的某个地方。我是一名新手程序员,也是bash的新手,所以对这些函数的解释将非常感激。

3 个答案:

答案 0 :(得分:0)

d1="/tmp/d1"
d2="/tmp/d2"
d3="/tmp/d3"

cd "${d1}"
for file in * ; do
    if [ ! -f "${d2}/${file}" ] ; then
        cp "${file}" "${d3}"
    fi
done
cd -

cd "${d2}"
for file in * ; do
    if [ ! -f "${d1}/${file}" ] ; then
        cp "${file}" "${d3}"
    fi
done
cd -

答案 1 :(得分:0)

for file in $(diff dir1 dir2 | sed 's/Only in \([^ ]*\): /\1\//'); do
    cp "$file" dir3/
done

diff dir1 dir2为您提供两个目录中都不存在的文件列表:

$ diff dir1 dir2
> Only in dir2: f3
> Only in dir1: f4
> Only in dir2: f5

我们通过对此进行管道以获取该文件的路径(也许diff可以选择执行此操作,我们不需要

$ diff dir1 dir2 | sed 's/Only in \([^ ]*\): /\1\//'
> dir2/f3
> dir1/f4
> dir2/f5

然后我们遍历此文件列表并将其复制到dir3

小心的子目录! (你有吗?)

让我们仔细看看命令:

sed 's/Only in \([^ ]*\): /\1\//'

s是替代命令,如果你是想用false替换true,你会使用s/true/false/。我们想要替换Only in \([^ ]*\):。第一部分只是diff命令的输出文本,然后我们使用转义的括号\(\)来匹配文件的名称,以便稍后再引用它(\1)。在括号内我们有[^ ]*,它匹配除了空格之外的所有内容(所以我们假设文件名没有空格,这可以改进!)。这与目录的名称匹配。然后我们匹配diff命令的更多文本,即:。所有这些都替换为\1,它只是\(\)(目录名称)中的一部分。我们最终得到了相关文件的完整路径。

答案 2 :(得分:0)

使用

的单线程解决方案
LANG=C diff -aqr /tmp/d1 /tmp/d2 |
    awk -F'[ :]' '/^Only in/{system("cp -a "$3"/"$NF " /tmp/d3/")}'

说明

  • LANG=C强制diff输出为英文,以便进行可解析的解析
  • diff -aqr /tmp/d1 /tmp/d2将以递归方式显示两个文件丢失或不同的文件
  • 我们使用awk来删除目录/文件名
  • -F'[ :]'表示:在空格和:
  • 上拆分列
  • '/ ^仅在/ is like a grep`中,如果找到模式,我们执行:
  • system("cp -a "$3"/"$NF " /tmp/d3/"):复制/ tmp / d3中的found_dir / found_file

警告

  • 脚本不处理名称中带空格的文件/目录,这需要额外的处理,但你现在有一个好的开始