Answers:
这是三个步骤的解决方案:
temeraire:tmp jenny$ find . -type f -name \*ENDING -exec dirname {} \; |sort -u > /tmp/ending.lst
temeraire:tmp jenny$ find . -type d |sort -u > /tmp/dirs.lst
temeraire:tmp jenny$ comm -3 /tmp/dirs.lst /tmp/ending.lst
comm -3 <(find . -type f -name \*ENDING -exec dirname {} \; |sort -u) <(find . -type d |sort -u)
开始了!
#!/usr/bin/env python3
import os
for curdir,dirnames,filenames in os.walk('.'):
if len(tuple(filter(lambda x: x.endswith('.ENDING'), filenames))) == 0:
print(curdir)
或替代(和更多的pythonic):
#!/usr/bin/env python3
import os
for curdir,dirnames,filenames in os.walk('.'):
# Props to Cristian Cliupitu for the better python
if not any(x.endswith('.ENDING') for x in filenames):
print(curdir)
额外的DLC内容!
find命令的(主要是)更正版本:
find . -type d \! -exec bash -c 'set nullglob; test -f "{}"/*.ENDING' \; -print
test: ...: binary operator expected
*.ENDING
next(filter(lambda x: x.endswith('.ENDING'), filenames))
也可以使用生成器理解来写next(x for x in filenames if x.endswith('.ENDING'))
。
if not any(x.endswith('.ENDING') for x in filenames)
基于以下事实:False
空可迭代的任何回报。
shell扩展了*
,但是在您的情况下,不涉及任何shell,仅涉及find所执行的测试命令。因此,将对其存在性进行测试的文件按字面命名为。*.ENDING
相反,您应该使用以下内容:
find . -type d \! -execdir sh -c 'test -e {}/*.ENDING' \; -print
执行测试时,这将导致sh扩展。*.ENDING
资料来源:在UX.SE上找到问题
-c: line 0: syntax error near unexpected token
(''我的目录名的格式。‘XYZ(dfdf)’其实它的口径库。
sh: line 0: test: foo1/bar.ENDING: binary operator expected
的目录包含以结尾的文件ENDING
。
sh: -c: line 0: syntax error near unexpected token
('sh:-c:line 0:'test -e test(test)/ * 。ending '。 / test(test)`。但是,当我将.end更改为.xyz时,会得到相同的结果,这是因为我以have头作为目录名称,对吗?我该如何解决呢?
受到Dennis Nolte和MikeyB的回答的启发,我想出了以下解决方案:
find . -type d \
\! -exec bash -c 'shopt -s failglob; echo "{}"/*.ENDING >/dev/null' \; \
-print 2>/dev/null
它基于以下事实而工作:
如果设置了failglob shell选项,但未找到匹配项,则会显示一条错误消息,并且不执行该命令。
顺便说一下,这就是为什么stderr被重定向到的原因/dev/null
。
我会亲自在perl中完成
#!/usr/bin/perl
use strict;
use warnings;
use File::Find;
#this sub is called by 'find' on each file it traverses.
sub checkdir {
#skip non directories.
return unless ( -d $File::Find::name );
#glob will return an empty array if no files math - which evaluates as 'false'
if ( not glob ( "$File::Find::name/*.ENDING" ) ) {
print "$File::Find::name does not contain any files that end with '.ENDING'\n";
}
}
#kick off the search on '.' - set a directory path or list of directories to taste.
# - you can specify multiple in a list if you so desire.
find ( \&checkdir, "." );
应该可以解决问题(适用于我非常简单的测试用例)。
这是一线寻找。
find ./ -type d ! -regex '.*.ENDING$' -printf "%h\n" | sort -u
编辑:糟糕,也不会工作。