我想为我的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。
谢谢!
答案 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标准的一部分,可能并非在所有实现中都可用。