在继续使用 SVN 之前,我曾经通过简单地保留一个/develop/
目录并在那里编辑和测试文件,然后将它们移动到该/main/
目录来管理我的项目。当我决定迁移到 SVN 时,我需要确保目录确实是同步的。
那么,编写 shell 脚本 [ bash ] 以递归比较两个不同目录中同名文件的好方法是什么?
注意:上面使用的目录名称仅用于示例。我不建议将您的代码存储在顶层:)。
diff 命令有一个 -r 选项来递归比较目录:
diff -r /develop /main
diff -rqu /develop /main
它只会以这种方式为您提供更改的摘要:)
如果您只想查看新的/丢失的文件
diff -rqu /develop /main | grep "^Only
如果你想让它们裸露:
diff -rqu /develop /main | sed -rn "/^Only/s/^Only in (.+?): /\1/p"
我可用的差异允许递归差异:
diff -r main develop
但是使用 shell 脚本:
( cd main ; find . -type f -exec diff {} ../develop/{} ';' )
[我在某处读到回答你自己的问题是可以的,所以这里是:)]
我试过这个,效果很好
[/]$ cd /develop/
[/develop/]$ find | while read line; do diff -ruN "/main/$line" $line; done |less
您可以选择仅比较特定文件 [例如,仅 .php 文件],方法是将上述行编辑为
[/]$ cd /develop/
[/develop/]$ find -name "*.php" | while read line; do diff -ruN "/main/$line" $line; done |less
还有其他想法吗?
这是我的一个(有些混乱的)脚本示例,dircompare.sh,它将:
diff -q
确定它们是否不同diff
声称相等的文件,显示并比较时间戳希望它可以有用 - 干杯!
EDIT2:(实际上,它适用于远程文件 - 问题是在本地和远程文件之间的差异操作期间未处理的 Ctrl-C 信号,这可能需要一段时间;脚本现在更新了一个陷阱来处理这个问题 - 但是,留下下面的先前编辑供参考):
编辑:...除了它似乎使我的服务器崩溃以获取远程 ssh 目录(我尝试使用 over ~/.gvfs
)...所以这不再是bash
了,但我想另一种方法是使用rsync
,这是一个示例:
$ # get example revision 4527 as testdir1
$ svn co https://openbabel.svn.sf.net/svnroot/openbabel/openbabel/trunk/data@4527 testdir1
$ # get earlier example revision 2729 as testdir2
$ svn co https://openbabel.svn.sf.net/svnroot/openbabel/openbabel/trunk/data@2729 testdir2
$ # use rsync to generate a list
$ rsync -ivr --times --cvs-exclude --dry-run testdir1/ testdir2/
sending incremental file list
.d..t...... ./
>f.st...... CMakeLists.txt
>f.st...... MACCS.txt
>f..t...... SMARTS_InteLigand.txt
...
>f.st...... atomtyp.txt
>f+++++++++ babel_povray3.inc
>f.st...... bin2hex.pl
>f.st...... bondtyp.h
>f..t...... bondtyp.txt
...
注意:
/
目录名称末尾的斜杠rsync
--dry-run
- 仅模拟,不更新/传输文件-r
- 递归到目录-v
- 详细(但与文件更改信息无关)--cvs-exclude
- 忽略.svn
文件-i
- “--itemize-changes:输出所有更新的变更摘要”以下是man rsync
解释由-i
(例如,>f.st......
上面的字符串)显示的信息的简短摘录:
The "%i" escape has a cryptic output that is 11 letters long.
The general format is like the string YXcstpoguax, where Y is
replaced by the type of update being done, X is replaced by the
file-type, and the other letters represent attributes that may
be output if they are being modified.
The update types that replace the Y are as follows:
o A < means that a file is being transferred to the remote
host (sent).
o A > means that a file is being transferred to the local
host (received).
o A c means that a local change/creation is occurring for
the item (such as the creation of a directory or the
changing of a symlink, etc.).
...
The file-types that replace the X are: f for a file, a d for a
directory, an L for a symlink, a D for a device, and a S for a
special file (e.g. named sockets and fifos).
The other letters in the string above are the actual letters
that will be output if the associated attribute for the item is
being updated or a "." for no change. Three exceptions to this
are: (1) a newly created item replaces each letter with a "+",
(2) an identical item replaces the dots with spaces, and (3) an
....
确实有点神秘 - 但至少它显示了基本的目录比较ssh
。干杯!
经典的(System V Unix)答案是dircmp dir1 dir2
,它是一个 shell 脚本,它会列出在 dir1 但不是 dir2 或在 dir2 但不是 dir1 中找到的文件(输出的第一页,来自pr
命令,所以用标题分页),然后将每个常见文件与分析进行比较(相同、不同、目录是最常见的结果)。
这似乎正在消失的过程中 - 如果您需要,我可以独立重新实现它。这不是火箭科学(cmp
是你的朋友)。