回答:
3つのステップでの解決策は次のとおりです。
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
があるという事実に基づいて使用すると、さらに優れたソリューションになると思います。
シェルはを展開*
しますが、あなたの場合、シェルは含まれていません。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) `。しかし、.endingを.xyzに変更しても同じ結果が得られます。これは、ディレクトリ名としてbractsがあるためです?どうすれば修正できますか?
Dennis NolteとMikeyBの答えに触発されて、私はこの解決策を思いつきました。
find . -type d \
\! -exec bash -c 'shopt -s failglob; echo "{}"/*.ENDING >/dev/null' \; \
-print 2>/dev/null
それはという事実に基づいて動作します
場合failglobのシェルオプションが設定され、一致するものが見つからない、エラーメッセージが出力され、コマンドが実行されません。
ところで、それが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
編集:おっと、どちらも動作しません。