内部に特定のファイル名を持つファイルがないすべてのディレクトリを一覧表示します


11

内部に特定のファイル名を持つファイルがないすべてのディレクトリを一覧表示するにはどうすればよいですか?たとえばこの木を与えられた

/
  /a
     README
     file001
     file002
  /b
     README
     file001
  /c
     file003

という名前のファイルがないディレクトリを一覧表示したいのですがREADME、この場合はディレクトリになり/cます。どうすればいいですか?例えば、を使用した構文は考えられませんfind


恥ああ恥あなたも検索しませんでした:askubuntu.com/questions/196960/...
SLMを

おそらく、検索するときに適切なキーワードを考えていませんでした。
レナン2013

2
私はあなたのチョップでただ破滅しています。何かを検索するための正しい単語を思いつかないことが何度もありました8)。
slm

回答:


5

への引数に埋め込まれたを受け入れるfindGNUのような実装を想定します。find{}-exec

$ find . -type d \! -exec test -e '{}/README' \; -print

ここで、ディレクトリ1/1から5/5にはREADMEがあり、他のディレクトリは空です。

$ tree 
.
|-- 1
|   `-- 1
|       `-- README
|-- 10
|   `-- 10
|-- 2
|   `-- 2
|       `-- README
|-- 3
|   `-- 3
|       `-- README
|-- 4
|   `-- 4
|       `-- README
|-- 5
|   `-- 5
|       `-- README
|-- 6
|   `-- 6
|-- 7
|   `-- 7
|-- 8
|   `-- 8
`-- 9
    `-- 9

このバージョンのfindコマンドを実行すると、次のようになります。

$ find . -type d \! -exec test -e '{}/README' \; -print
.
./10
./10/10
./7
./7/7
./9
./9/9
./6
./6/6
./5
./8
./8/8
./4
./1
./3
./2

参考文献


コマンドを変更して、特定のファイル拡張子(* .txtなど)がないサブディレクトリを検索する方法。* .txtを使用してREADMEを変更しても機能しないようです
WanderingMind

@WanderingMind-新しい質問がある場合は、サイトで新しい質問として質問してください;-)
slm

3

-execオプションを使用findしてファイルをチェックし、チェックが失敗したすべての結果を印刷できます。

find /path/to/base -mindepth 1 -maxdepth 1 -type d -exec test -e {}/README \; -o -print

3

必要はありませんfind。シェルを使用するだけです:

for d in */; do [ -f "$d"README ] || printf '%s\n' "$d"; done
c/

あなたはそれを再帰的にする必要がある場合は、(のために使用することができbashzshデフォルトで使用これを行うことができますset -o globstarでのksh93):

shopt -s globstar
for d in **/; do [ -f "$d"README ] || printf '%s\n' "$d"; done

(ドットファイルはデフォルトで除外されることに注意してください)。


2

With zshおよびglob修飾子estring):

print -rl -- *(/e_'[[ ! -f $REPLY/README ]]'_)

または

print -rl -- *(/^e_'[[ -f $REPLY/README ]]'_)

追加Dして隠しディレクトリを含める:

print -rl -- *(D/e_'[[ ! -f $REPLY/README ]]'_)

/ディレクトリのみe_'[[ ! -f $REPLY/README ]]'_を選択し、さらに引用符で囲まれたシェルコードが返すディレクトリ名のみを選択しますtrue$REPLYつまり、グロブが*(/)展開される各ディレクトリ名()に対して実行され[[ ! -f $REPLY/README ]]、結果がであればディレクトリの名前を保持しtrueます。
2番目の形式^e_'.....'_は、同じglob修飾子を否定して使用します(ただし、今回は条件式は否定されません:)[[ -f $REPLY/README ]]


上記は現在のディレクトリのディレクトリ名のみを返します。
再帰的に検索する場合(ここでも、隠しディレクトリを含めるにはD修飾子を追加します):

print -rl ./**/*(/e_'[[ ! -f $REPLY/README ]]'_)

2

移植性が高く、次のことができます。

find . -type d -exec sh -c '
  for dir do
    [ -f "$dir/README" ] || printf "%s\n" "$dir"
  done' sh '{}' +

[ -f file ]ファイルが存在 、通常のファイルであることが確認されたかどうかをテストします(シンボリックリンクの解決後)。

タイプに関係なく、それが(そのディレクトリのエントリとして)のみ存在することをテストする場合は、次のものが必要です[ -e file ] || [ -L file ]。ただし、これらのテストを実行するには、ディレクトリへの検索権限が必要です。次の[ -x "$dir" ]ような場合に対応するために、いくつかのテストを追加することができます。

find . -type d -exec sh -c '
  for dir do
    if [ -x "$dir" ]; then
      [ -f "$dir/README" ] || printf "%s\n" "$dir"
    else
      printf >&2 "Cannot tell for \"%s\"\n" "$dir"
    fi
  done' sh '{}' +

または、次のようにして、競合状態を回避しzshます。

find . -type d -exec zsh -c '
  zmodload zsh/system
  for dir do
    ERRNO=0
    if [ ! -f "$dir/README" ]; then
      if [ "$errnos[ERRNO]" = ENOENT ]; then
        printf "%s\n" "$dir"
      else
        syserror -p "ERROR: $dir/README: "
      fi
    fi
  done' zsh '{}' +

参照してくださいBashに通常のファイルが存在しないかどうかを確認するにはどうすればよいですか?SOで。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.