从bash shell中的find中排除文件扩展名列表

时间:2017-05-17 16:16:30

标签: linux makefile find

我想为我的make文件编写一个清理例程,除了我文件夹中的必要源文件之外,它除去了所有东西。例如,我的文件夹包含具有以下扩展名的文件:.f .f90 .F90 .F03 .o .h .out .dat .txt .hdf .gif。

我知道我可以通过以下方式实现这一目标:

find . -name \( '*.o' '*.out' '*.dat' '*.txt' '*.hdf' '*.gif' \) -delete

使用否定,我可以这样做:

find . -not -name '*.f*' -not -name '*.F*' -not -name '*.h' -delete

但是,当我尝试这样做时:

find . -not -name \( '*.f*' '*.F*' '*.h' \)

我收到错误:

find: paths must exceed expression: [first expression in the above list]

(在这种情况下,我会得到: find: paths must exceed expression: *.f*

你能解释为什么会这样,以及如何做我想做的事情?每次我想在列表中添加文件扩展名时,我都讨厌编写-not -name。另外,我想找出为什么这会给我一个错误,以便我可以更好地学习Linux。

谢谢!

1 个答案:

答案 0 :(得分:6)

find . -not -name \( '*.f' '*.F' '*.h' \)

被解释为

find
    .                      # path to search
    -not                   # negate next expression
    -name \(               # expression for files named "("
    '*.f' '*.F' .'*.h' \)  # more paths to search?

导致错误。

由于这些是单字母扩展名,您可以将它们折叠为单个glob:

find . -not -name '*.[fFh]'

但如果它们更长,你必须写出全球

find . -not -name '*.f' -not -name '*.F' -not -name '*.h'

find . -not \( -name '*.f' -o -name '*.F' -o -name '*.h' \)

或切换到使用正则表达式。

find . -not -regex '.*\.(f|F|h)$'

请注意find中的正则表达式不是POSIX标准的一部分,可能并非在所有实现中都可用。