在 Unix 上查找不以特定扩展名结尾的文件名?
Posted
技术标签:
【中文标题】在 Unix 上查找不以特定扩展名结尾的文件名?【英文标题】:find filenames NOT ending in specific extensions on Unix? 【发布时间】:2010-11-23 09:51:30 【问题描述】:有没有一种简单的方法可以递归地查找目录层次结构中的所有文件,不 以扩展名列表结尾?例如。所有不是 *.dll 或 *.exe 的文件
UNIX/GNU find,虽然功能强大,但似乎没有exclude
模式(或者我错过了它),而且我一直发现很难使用正则表达式来查找不匹配特定的表达式。
我在 Windows 环境中(使用大多数 GNU 工具的GnuWin32 端口),所以我同样愿意接受仅限 Windows 的解决方案。
【问题讨论】:
这个问题在这里有更多答案:List files not matching a pattern? 【参考方案1】:或者没有(
并且需要转义它:
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
【讨论】:
-not
可以替换为'!'
(推荐引用)。另一方面,-name
区分大小写,而 -iname
不区分大小写。【参考方案2】:
find . ! \( -name "*.exe" -o -name "*.dll" \)
【讨论】:
在 Solaris 上-not
是一个糟糕的选择,这个带有 !
的效果很好:)【参考方案3】:
$ find . -name \*.exe -o -name \*.dll -o -print
前两个 -name 选项没有 -print 选项,因此它们被跳过。其他所有内容均已打印。
【讨论】:
【参考方案4】:你可以使用 grep 命令做一些事情:
find . | grep -v '(dll|exe)$'
grep
上的 -v
标志专门表示“查找与此表达式不匹配的内容。”
【讨论】:
grep -v '\.(dll|exe)$' 例如,会阻止匹配名为“dexe”的文件或目录 这只适用于扩展的正则表达式。我必须添加 -E(或使用 egrep)才能完成这项工作。 你可以使用两个表达式来代替-E
: grep -v -e '\.dll$' -e '\.exe$'
【参考方案5】:
还有一个:-)
$ ls -ltr 共 10 个 -rw-r--r-- 1 脚本编写者 linuxdumb 47 Dec 23 14:46 test1 -rw-r--r-- 1 脚本编写者 linuxdumb 0 Jan 4 23:40 test4 -rw-r--r-- 1 脚本编写者 linuxdumb 0 Jan 4 23:40 test3 -rw-r--r-- 1 脚本编写者 linuxdumb 0 Jan 4 23:40 test2 -rw-r--r-- 1 脚本编写者 linuxdumb 0 Jan 4 23:41 file5 -rw-r--r-- 1 脚本编写者 linuxdumb 0 Jan 4 23:41 file4 -rw-r--r-- 1 脚本编写者 linuxdumb 0 Jan 4 23:41 file3 -rw-r--r-- 1 脚本编写者 linuxdumb 0 Jan 4 23:41 file2 -rw-r--r-- 1 脚本编写者 linuxdumb 0 Jan 4 23:41 file1 $查找。 -类型 f ! -名称“*1”! -name "*2" -print ./test3 ./test4 ./文件3 ./file4 ./file5 $
Unix find command reference
【讨论】:
【参考方案6】:find /data1/batch/source/export -type f -not -name "*.dll" -not -name "*.exe"
【讨论】:
【参考方案7】: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 风格是最强大的风格。
(2) grep 中的 v 选项指示 shell 排除任何满足正则表达式的文件
(3) say ".dll$" 末尾的 $ 字符是一个分隔符控制字符,它告诉 shell 文件名字符串以 ".dll" 结尾
【讨论】:
【参考方案8】:如果您有很长的扩展列表 - 维护一长串 -not -name 'this' -not -name 'that' -not -name 'other'
会很乏味且容易出错 - 或者如果搜索是程序化的并且扩展列表很长,则此页面上的其他解决方案是不可取的是在运行时构建的。
对于这些情况,可能需要更清楚地分离数据(扩展列表)和代码(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。
【讨论】:
以上是关于在 Unix 上查找不以特定扩展名结尾的文件名?的主要内容,如果未能解决你的问题,请参考以下文章