有没有一种简单的方法来递归查找目录层次结构中所有不以特定扩展名结尾的文件?例如,所有不是*.dll或*.exe的文件。
UNIX / GNU find非常强大,但似乎没有排除
模式(或者我可能没有发现),而且我一直觉得很难使用正则表达式来查找与特定表达式不匹配的内容。
我在Windows环境中(使用大多数GNU工具的GnuWin32端口),因此我同样开放接受仅限Windows的解决方案。
有没有一种简单的方法来递归查找目录层次结构中所有不以特定扩展名结尾的文件?例如,所有不是*.dll或*.exe的文件。
UNIX / GNU find非常强大,但似乎没有排除
模式(或者我可能没有发现),而且我一直觉得很难使用正则表达式来查找与特定表达式不匹配的内容。
我在Windows环境中(使用大多数GNU工具的GnuWin32端口),因此我同样开放接受仅限Windows的解决方案。
或者不需要使用(
并且不需要对其进行转义:
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
find . ! \( -name "*.exe" -o -name "*.dll" \)
-not
选项不太好用,但加上感叹号(!
)就很好用了 :) - DmitrySandalov$ find . -name \*.exe -o -name \*.dll -o -print
前两个-name选项没有-print选项,因此被跳过。其他所有内容都会被打印。
find . | grep -v '(dll|exe)$'
< p > 在 < code > grep 命令中,< code > -v 标志特指"查找不匹配该表达式的内容"。 < /p >
-E
:grep -v -e '\.dll$' -e '\.exe$'
。 - alx - recommends codidactfind /data1/batch/source/export -type f -not -name "*.dll" -not -name "*.exe"
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 命令结合使用正则表达式,我认为 Perl 风格是最强大的风格。
(2) 在 grep 命令中,选项 v 会让 shell 排除所有符合正则表达式的文件。
(3) 在 ".dll$" 中,$ 字符是一个分隔符控制字符,告诉 shell 文件名字符串以 ".dll" 结尾。
还有一个 :-)
$ ls -ltr 总计 10 -rw-r--r-- 1 scripter linuxdumb 47 12月 23 14:46 test1 -rw-r--r-- 1 scripter linuxdumb 0 1月 4 23:40 test4 -rw-r--r-- 1 scripter linuxdumb 0 1月 4 23:40 test3 -rw-r--r-- 1 scripter linuxdumb 0 1月 4 23:40 test2 -rw-r--r-- 1 scripter linuxdumb 0 1月 4 23:41 file5 -rw-r--r-- 1 scripter linuxdumb 0 1月 4 23:41 file4 -rw-r--r-- 1 scripter linuxdumb 0 1月 4 23:41 file3 -rw-r--r-- 1 scripter linuxdumb 0 1月 4 23:41 file2 -rw-r--r-- 1 scripter linuxdumb 0 1月 4 23:41 file1 $ find . -type f ! -name "*1" ! -name "*2" -print ./test3 ./test4 ./file3 ./file4 ./file5 $
使用-not与-regex一起
find . -type f -not -regex '.*\.\(exe\|dll\)'
如果您有一个长的扩展名列表,维护一长串-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。