你如何区分一个目录只包含特定类型的文件?
Posted
技术标签:
【中文标题】你如何区分一个目录只包含特定类型的文件?【英文标题】:How do you diff a directory for only files of a specific type? 【发布时间】:2010-09-23 04:02:02 【问题描述】:我对 diff 命令有疑问 如果我想要一个递归目录差异但只针对特定的文件类型,该怎么做?
我尝试使用排除选项,但只能使用一种模式:
$ diff /destination/dir/1 /destination/dir/2 -r -x *.xml
使用该命令我只能排除 xml 文件类型,即使文件夹图像类型中有文件(png
、gif
、jpg
)、txt
、php
等
如何仅区分某些文件类型。
【问题讨论】:
***.com/q/10131908/2707864 那么您是要区分特定类型的文件还是排除这些文件的差异?这个问题与描述无关.. 【参考方案1】:您可以多次指定-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 匹配的子目录。 与 shell 不同,文件名开头的句点 匹配模式开头的通配符。你应该附上 引号中的 PATTERN 以便 shell 不会扩展它。例如, 选项 -x '*.[ao]' 忽略名称以 '.a' 或 '.o'。
如果您多次指定此选项,则会累积该选项。为了 例如,使用选项 -x 'RCS' -x '*,v' 会忽略任何文件或 基本名称为“RCS”或以“,v”结尾的子目录。
【讨论】:
我的(ubuntu 10.04)没有这些行。我也试过了,还是不行。我猜这是一个新版本。【参考方案2】:取自(一个版本的)手册页:
-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
【讨论】:
您可以使用以下命令行在您的文件夹中找到除find . -type f -not -name '*.<my-ext>' | xargs -I% basename '%' | awk -F . 'NF > 1 print "*." $NF; NF == 1 print $NF ' | sort | uniq > exclude.pats
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]"
是可以的,但它不是很能说明问题)【参考方案3】:
你也可以使用 find 和 -exec 来调用 diff:
cd /destination/dir/1
find . -name *.xml -exec diff /destination/dir/2/ \;
【讨论】:
【参考方案4】:缺少补充的 --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
【讨论】:
超级有用的单线,谢谢。在 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
【参考方案5】:
我使用以下命令查找DIR1
和DIR2
之间所有*.tmpl
文件的差异。在我的情况下,这并没有产生任何误报,但它可能对你来说,这取决于你的 DIRS 的内容。
diff --brief DIR1 DIR2 | grep tmpl
【讨论】:
【参考方案6】:由于缺乏补充的 --include 使得有必要使用这样复杂的启发式模式
*.[A-Zb-ik-uw-z]*
查找(主要是)java 文件!
【讨论】:
【参考方案7】:如果您想区分来源并保持简单:
diff -rqx "*.a" -x "*.o" -x "*.d" ./PATH1 ./PATH2 | grep "\.cpp " | grep "^Files"
如果要获取仅存在于其中一个路径中的文件,请删除最后一个 grep。
【讨论】:
我喜欢简单 :-) 在德语中将grep "^Files"
更改为 grep "^Dateien"
【参考方案8】:
如果您觉得方便,可以使用以下Makefile
。只需运行:“make patch”
#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
【讨论】:
【参考方案9】:虽然它不能避免其他文件的实际diff
,但如果您的目标是生成补丁文件或类似文件,则可以使用patchutils
包中的filterdiff
,例如仅修补您的 .py
更改:
diff -ruNp /path/1 /path/2 | filterdiff -i "*.py" | tee /path/to/file.patch
【讨论】:
以上是关于你如何区分一个目录只包含特定类型的文件?的主要内容,如果未能解决你的问题,请参考以下文章