有没有一种简单的方法来递归地找到目录层次结构中的所有文件,其中不以扩展名列表结尾?例如,所有不是*.dll或*.exe的文件
UNIX/GNU find,尽管它很强大,但似乎没有exclude模式(或者我错过了它),而且我总是发现很难使用正则表达式来找到不匹配特定表达式的东西。
exclude
我在Windows环境中(使用大多数GNU工具的GnuWin32端口),所以我对Windows专用解决方案同样开放。
你可以使用grep命令做一些事情:
find . | grep -v '(dll|exe)$'
grep上的-v标志特别表示“查找与不匹配的表达式”。
grep
-v
find . ! \( -name "*.exe" -o -name "*.dll" \)
$ find . -name \*.exe -o -name \*.dll -o -print
前两个name选项没有-print选项,所以跳过了。其他的都打印出来了。
或者没有(并且需要转义它:
(
find . -not -name "*.exe" -not -name "*.dll"
同时也排除了目录列表
find . -not -name "*.exe" -not -name "*.dll" -not -type d
或者在实证逻辑中;-)
find . -not -name "*.exe" -not -name "*.dll" -type f
还有一个:-)
$ ls -ltr total 10 -rw-r--r-- 1 scripter linuxdumb 47 Dec 23 14:46 test1 -rw-r--r-- 1 scripter linuxdumb 0 Jan 4 23:40 test4 -rw-r--r-- 1 scripter linuxdumb 0 Jan 4 23:40 test3 -rw-r--r-- 1 scripter linuxdumb 0 Jan 4 23:40 test2 -rw-r--r-- 1 scripter linuxdumb 0 Jan 4 23:41 file5 -rw-r--r-- 1 scripter linuxdumb 0 Jan 4 23:41 file4 -rw-r--r-- 1 scripter linuxdumb 0 Jan 4 23:41 file3 -rw-r--r-- 1 scripter linuxdumb 0 Jan 4 23:41 file2 -rw-r--r-- 1 scripter linuxdumb 0 Jan 4 23:41 file1 $ find . -type f ! -name "*1" ! -name "*2" -print ./test3 ./test4 ./file3 ./file4 ./file5 $
Unix查找命令参考
Linux / OS X:
从当前目录开始,递归地找到所有以.dll或.exe结尾的文件
find . -type f | grep -P "\.dll$|\.exe$"
从当前目录开始,递归地找到所有不以.dll或.exe结尾的文件
find . -type f | grep -vP "\.dll$|\.exe$"
注:
(1) grep中的P选项表明我们正在使用Perl样式来编写正则表达式,与grep命令一起使用。为了与正则表达式一起执行grep命令,我发现Perl样式是最强大的样式。
grep中的v选项指示shell排除任何满足正则表达式的文件
(3)在".dll$"结尾的$字符是一个分隔符控制字符,它告诉shell文件名字符串以".dll"结尾。
如果你有一个很长的扩展列表——维护一个很长的-not -name 'this' -not -name 'that' -not -name 'other'序列将是乏味且容易出错的——或者如果搜索是编程式的,并且扩展列表是在运行时构建的,那么本页上的其他解决方案就不可取了。
-not -name 'this' -not -name 'that' -not -name 'other'
对于这些情况,可能需要更清楚地分离数据(扩展名列表)和代码(find的参数)的解决方案。给定一个目录&文件结构如下所示:
find
. └── a ├── 1.txt ├── 15.xml ├── 8.dll ├── b │ ├── 16.xml │ ├── 2.txt │ ├── 9.dll │ └── c │ ├── 10.dll │ ├── 17.xml │ └── 3.txt ├── d │ ├── 11.dll │ ├── 18.xml │ ├── 4.txt │ └── e │ ├── 12.dll │ ├── 19.xml │ └── 5.txt └── f ├── 13.dll ├── 20.xml ├── 6.txt └── g ├── 14.dll ├── 21.xml └── 7.txt
你可以这样做:
## data section, list undesired extensions here declare -a _BADEXT=(xml dll) ## code section, this never changes BADEXT="$( IFS="|" ; echo "${_BADEXT[*]}" | sed 's/|/\\|/g' )" find . -type f ! -regex ".*\.\($BADEXT\)"
结果是:
./a/1.txt ./a/b/2.txt ./a/b/c/3.txt ./a/d/4.txt ./a/d/e/5.txt ./a/f/6.txt ./a/f/g/7.txt
您可以在不更改代码块的情况下更改扩展列表。
请注意不能与本机OSX find一起工作-请使用gnu find代替。
find /data1/batch/source/export -type f -not -name "*.dll" -not -name "*.exe"
与-regex一起使用-not
find . -type f -not -regex '.*\.\(exe\|dll\)'