如何只为特定类型的文件区分目录?


87

如果要递归目录diff但仅针对特定文件类型,我对diff命令有疑问,该怎么办?

我尝试使用exclude选项,但只能使用一种模式:

$ diff /destination/dir/1 /destination/dir/2 -r -x *.xml

用命令我只能排除XML文件类型,即使是在文件夹中的图像类型(文件pnggifjpgtxtphp

如何仅区分某些文件类型。



那么,您是要比较特定类型的文件还是要排除这些文件?问题与描述无关
def

Answers:


97

您可以指定-x多个。

diff -x '*.foo' -x '*.bar' -x '*.baz' /destination/dir/1 /destination/dir/2

info diff(在我的系统上,必须做info -f /usr/share/info/diff.info.gz)的“比较目录”部分:

要在比较目录时忽略某些文件,请使用'-x PATTERN'或'--exclude = PATTERN'选项。此选项将忽略基本名称与外壳模式PATTERN相匹配的所有文件或子目录。与外壳程序不同,文件名基名开头的句点与模式开头的通配符匹配。您应该将PATTERN括在引号中,以便外壳程序不会对其进行扩展。例如,选项-x'*。[ao]'将忽略名称以'.a'或'.o'结尾的任何文件。

如果多次指定此选项,则会累积该选项。例如,使用选项-x'RCS'-x'*,v'将忽略基本名称为'RCS'或以',v'结尾的任何文件或子目录。


我的(ubuntu 10.04)没有这些限制。我也尝试过,但是没有用。我想这是一个新版本。
alumi 2013年

22

摘自手册页的一个版本:

-x PAT  --exclude=PAT
  Exclude files that match PAT.

-X FILE    --exclude-from=FILE
  Exclude files that match any pattern in FILE.

因此,看起来-x您报告时只接受一种模式,但是如果将所有要排除的模式放入文件中(大概每行一种),则可以使用第二个标记,如下所示:

$ diff /destination/dir/1 /destination/dir/2 -r -X exclude.pats

其中exclude.pats是:

*.jpg
*.JPG
*.xml
*.XML
*.png
*.gif

4
您可以使用以下命令行在文件夹中找到除<my-ext>扩展名之外的所有文件扩展名:find . -type f -not -name '*.<my-ext>' | xargs -I% basename '%' | awk -F . 'NF > 1 { print "*." $NF}; NF == 1 { print $NF }' | sort | uniq > exclude.pats
John

我希望我早些时候注意到John的评论,但是在macOs / bash上,我采用了一种类似的解决方案来生成具有几种保留模式的排除文件:find . -not -name "*.c" -and -not -name "*.h" -and -type f -print0 | xargs -0 basename | grep -E '.*\..+' | sed 's/\./\//g' | xargs basename | xargs printf '*.%s\n' | sort | uniq > X-FILE我想相信这会有所帮助,也许在Linux上也是如此。(在此示例中,可以单打-name "*.[ch]",但是说明性不是很高)
掩盖了


7

缺少补充--include...。

我们可以采取一种解决方法,将所有文件都包含但我们想要包含的文件排除在外。因此,我们file1使用查找来创建所有不具有我们要包含的扩展sed名的文件,并捕获文件名而只是:

diff --exclude-from=file1  PATH1/ PATH2/

例如:

find  PATH1/ -type f | grep --text -vP "php$|html$" | sed 's/.*\///' | sort -u > file1 
diff PATH1/ PATH2/ -rq -X file1 

超级有用的一线,thx。在Mac OSX上,grep略有不同,它变为 find PATH1/ -type f | grep --text -v -e "php$" -e html$" | sed 's/.*\///' | sort -u > file1 diff PATH1/ PATH2/ -rq -X file1
mmacvicar,2016年

3

我使用以下命令查找和*.tmpl之间所有文件的差异。就我而言,这不会产生任何误报,但这可能对您有利,这取决于您DIRS的内容。DIR1DIR2

diff --brief DIR1 DIR2 | grep tmpl


2

如果您觉得方便,可以使用以下命令Makefile。只需运行:“制作补丁”

#Makefile for patches

#Exlude following file endings
SUFFIX += o
SUFFIX += so
SUFFIX += exe
SUFFIX += pdf
SUFFIX += swp

#Exlude following folders
FOLDER += bin
FOLDER += lib
FOLDER += Image
FOLDER += models

OPTIONS = Naur

patch: 
    rm test.patch
    diff -$(OPTIONS) \
    $(foreach element, $(SUFFIX) , -x '*.$(element)') \
    $(foreach element, $(FOLDER) , -x '$(element)*') \
        org/ new/ > test.patch  

unpatch: 
    rm test.unpatch
    diff -$(OPTIONS) \
    $(foreach element, $(SUFFIX) , -x '*.$(element)') \
    $(foreach element, $(FOLDER) , -x '$(element)*') \
    new/ org/ > test.unpatch

1

缺少补充--include使得有必要使用复杂的启发式模式,例如

*.[A-Zb-ik-uw-z]*

查找(大部分)java文件!


1

如果您想改变来源并保持简单:

diff -rqx "*.a" -x "*.o" -x "*.d" ./PATH1 ./PATH2 | grep "\.cpp " | grep "^Files"

如果要获取仅存在于其中一个路径中的文件,请删除最后一个grep。


0

尽管它不能避免diff其他文件的出现,但如果您的目标是生成补丁文件或类似文件,则可以filterdiffpatchutils软件包中使用它,例如,仅补丁您的.py更改:

diff -ruNp /path/1 /path/2 | filterdiff -i "*.py" | tee /path/to/file.patch
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.