我希望运行一个Linux命令,它将递归地比较两个目录,并只输出不同目录的文件名。这包括在一个目录中而不在另一个目录中的任何内容,反之亦然,以及文本差异。
当前回答
在我的linux系统上获取文件名
diff -q /dir1 /dir2|cut -f2 -d' '
其他回答
rsync -rvc --delete --size-only --dry-run source dir target dir
运行diff -qr old/ new/的方法有一个主要缺点:它可能会错过新创建目录中的文件。例如,在下面的例子中,文件data/pages/playground/playground.txt不在diff -qr old/ new/的输出中,而目录data/pages/playground/是(在浏览器中搜索playground.txt以快速比较)。我还在Unix和Linux Stack Exchange上发布了以下解决方案,但我也将它复制到这里:
要以编程方式创建一个新的或修改过的文件列表,我能想到的最好的解决方案是使用rsync, sort和uniq:
(rsync -rcn --out-format="%n" old/ new/ && rsync -rcn --out-format="%n" new/ old/) | sort | uniq
让我用这个例子来解释:我们希望比较两个dokuwiki版本,以查看哪些文件被更改,哪些文件是新创建的。
我们使用wget获取tar文件,并将它们提取到old/和new/目录中:
wget http://download.dokuwiki.org/src/dokuwiki/dokuwiki-2014-09-29d.tgz
wget http://download.dokuwiki.org/src/dokuwiki/dokuwiki-2014-09-29.tgz
mkdir old && tar xzf dokuwiki-2014-09-29.tgz -C old --strip-components=1
mkdir new && tar xzf dokuwiki-2014-09-29d.tgz -C new --strip-components=1
以一种方式运行rsync可能会错过新创建的文件,rsync和diff的比较如下所示:
rsync -rcn --out-format="%n" old/ new/
输出如下:
VERSION
doku.php
conf/mime.conf
inc/auth.php
inc/lang/no/lang.php
lib/plugins/acl/remote.php
lib/plugins/authplain/auth.php
lib/plugins/usermanager/admin.php
只在一个方向上运行rsync会错过新创建的文件,而反过来则会错过已删除的文件,比较diff的输出:
diff -qr old/ new/
输出如下:
Files old/VERSION and new/VERSION differ
Files old/conf/mime.conf and new/conf/mime.conf differ
Only in new/data/pages: playground
Files old/doku.php and new/doku.php differ
Files old/inc/auth.php and new/inc/auth.php differ
Files old/inc/lang/no/lang.php and new/inc/lang/no/lang.php differ
Files old/lib/plugins/acl/remote.php and new/lib/plugins/acl/remote.php differ
Files old/lib/plugins/authplain/auth.php and new/lib/plugins/authplain/auth.php differ
Files old/lib/plugins/usermanager/admin.php and new/lib/plugins/usermanager/admin.php differ
以两种方式运行rsync并对输出进行排序以删除重复项,发现目录data/pages/playground/和文件data/pages/playground/playground.txt最初被遗漏了:
(rsync -rcn --out-format="%n" old/ new/ && rsync -rcn --out-format="%n" new/ old/) | sort | uniq
输出如下:
VERSION
conf/mime.conf
data/pages/playground/
data/pages/playground/playground.txt
doku.php
inc/auth.php
inc/lang/no/lang.php
lib/plugins/acl/remote.php
lib/plugins/authplain/auth.php
lib/plugins/usermanager/admin.php
Rsync使用以下参数运行:
-r“递归到目录”, -c也比较相同大小的文件,只“跳过基于校验和,而不是mod-time和大小”, -n“执行不做任何更改的试运行”,以及 ——out-format="%n"到"使用指定格式输出更新",这里的"%n"仅用于文件名
使用sort对两个方向的rsync输出(文件列表)进行组合和排序,然后使用uniq删除所有重复项来压缩这个排序的列表
您也可以使用rsync
rsync -rv --size-only --dry-run /my/source/ /my/dest/ > diff.out
如果你想获取一个文件列表,这些文件只在一个目录中,而不是它们的子目录,只有它们的文件名:
diff -q /dir1 /dir2 | grep /dir1 | grep -E "^Only in*" | sed -n 's/[^:]*: //p'
如果你想递归列出所有的文件和目录,它们的完整路径是不同的:
diff -rq /dir1 /dir2 | grep -E "^Only in /dir1*" | sed -n 's/://p' | awk '{print $3"/"$4}'
这样就可以对所有文件应用不同的命令。
例如,我可以删除dir1而不是dir2中的所有文件和目录:
diff -rq /dir1 /dir2 | grep -E "^Only in /dir1*" | sed -n 's/://p' | awk '{print $3"/"$4}' xargs -I {} rm -r {}
在我的linux系统上获取文件名
diff -q /dir1 /dir2|cut -f2 -d' '
推荐文章
- Linux Bash中双&和分号有什么区别?
- 如何合并2 JSON对象从2个文件使用jq?
- 在SSH会话中查找客户端的IP地址
- C++ Linux的想法?
- 如何为Fedora安装g++ ?
- 如何触发命令行PHP脚本的XDebug分析器?
- Linux删除大小为0的文件
- 使用ImageMagick“Diff”图像
- Maven命令行如何指向特定的settings.xml为单个命令?
- Spring引导应用程序作为服务
- Git分支之间的视觉差异
- 如何重定向标准derr和标准输出到不同的文件在同一行脚本?
- Windows和Linux上的c++编译:ifdef开关
- Linux: kill后台任务
- 如何循环通过文件匹配通配符在批处理文件