是否有一种简单的方法来递归地找到目录层次结构中的所有文件,而不是以扩展名列表结束?例如,所有不是*.dll或*.exe的文件

UNIX/GNU find虽然功能强大,但似乎没有排除模式(或者我错过了它),而且我总是发现很难使用正则表达式来查找与特定表达式不匹配的内容。

我在Windows环境中(使用大多数GNU工具的GnuWin32端口),所以我同样对Windows专用解决方案持开放态度。


当前回答

你可以使用grep命令做一些事情:

find . | grep -v '(dll|exe)$'

grep上的-v标志特别表示“查找不匹配此表达式的内容”。

其他回答

你可以使用grep命令做一些事情:

find . | grep -v '(dll|exe)$'

grep上的-v标志特别表示“查找不匹配此表达式的内容”。

$ find . -name \*.exe -o -name \*.dll -o -print

前两个name选项没有-print选项,所以跳过了。其他的都打印出来了。

如果您有一个很长的扩展列表——维护一个长序列的-not -name 'this' -not -name 'that' -not -name ' Other '将是乏味且容易出错的——或者如果搜索是编程式的,并且扩展列表是在运行时构建的,那么此页上的其他解决方案是不可取的。

对于这些情况,可能需要更清楚地分离数据(扩展列表)和代码(要查找的参数)的解决方案。给定一个目录和文件结构,看起来像这样:

.
└── 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"

或者没有(并且需要逃避它:

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