1つ以上のファイルを含むすべてのディレクトリを見つける方法は?

1つ以上のファイルを含むすべてのディレクトリを見つける方法は?

ディレクトリ階層があります。一部のディレクトリにはファイルがなく、他のディレクトリのみが含まれています。一部にはファイルが含まれます。

たとえば、

- movies
  - 2022
    - action
      - movie.mp4
      - another-movie.mp4
  - 2023
    - drama
      - movie2.mp4
  - 2024
    - thriller
      - movie3.mp4
    - movie4.mp4

find私はこの結果を与えるコマンドが欲しい:

/movies/2022/action
/movies/2023/drama
/movies/2024
/movies/2024/thriller

私は読んだこれそしてこれそしてこれfindしかし、コマンドを見つけることはできません。

修正する: ディレクトリにはファイルとディレクトリを含めることができます。質問を更新しました。たとえば、2024映画とは異なるディレクトリがあります。結果には目次を/movies/2024含める必要があります。/movies/2024/thriller

答え1

ファイル形式の検索定期的な含まれているディレクトリを印刷します。リストは、各ディレクトリが一度だけリストされるように一意です。 GNUシステムでは、改行文字を含むファイルパスがある場合でも、これを確実に行うことができます。

find /path -type f -print0 |
    LC_ALL=C sed -z 's!/[^/]*$!!' |
    LC_ALL=C sort -zu |
    tr '\0' '\n'

標準では、ファイルパスに改行文字が含まれていないと仮定しています。

find /path -type f -print |
    LC_ALL=C sed 's!/[^/]*$!!' |
    LC_ALL=C sort -u

答え2

単に、

find movies -type f -print | \
    xargs -r dirname | \
    sort --uniq

読むman find xargs dirname sort

説明は次のとおりです。

  • findすべてのファイルとそのディレクトリのリストを出力/movies/2022/action/movie.mp4 /movies/2022/action/another-movie.mp4 ...しますSTDOUT
  • xargsできるだけ多くのファイル名を圧縮し(参考資料を参照xargs --show-limits </dev/null)、ファイル名が不足するdirnameまで繰り返します。xargs
  • dirname一番右/とファイル名を切り取ります。たとえば/movies/2022/action/movie.mp4/movies/2022/action/movies/2022/action/another-movie.mp4/movies/2022/action/
  • sort --unique重複したディレクトリ名を削除します。

この構造(find、、、xargs後処理)は多くの作業に役立ちます。それを理解するために少し努力してください。

答え3

これにより、トリックを実行できます。

find /movies -type d -not -empty -links 2

見積もりこの回答:

リンク数は、ファイルへのハードリンク数です。ディレクトリの場合、ハードリンクの数は、(直接)サブディレクトリの数に親ディレクトリとそれ自体を加えた数です。

したがって、リンク数が2つの場合、親ディレクトリ(..)と独自のディレクトリ(.)のみがあるため、子ディレクトリはありません。


この回答は元の質問には効果がありましたが、後で更新された質問には機能しません。他の人に役立つかもしれないので残しておきます。

答え4

免責事項:私は現在rawhide(rh)の著者です(github.com/raforg/rawhideを参照)。

生皮(rh)を使用すると、次のことができます。

rh /movies 'd && !empty && "[ -n \"$(rh -ref -- %S)\" ]".sh'

/movies検索パスです。

残りは検索基準だけです。

dディレクトリという意味です。

!empty空ではないという意味だ。これは必須ではありませんが、次に作成されるシェルプロセスの数を減らすことで、作業を高速化できます。

"[ -n \"$(rh -ref -- %S)\" ]".shシェルコマンドを実行して、[ -n "$(rh -ref -- %S)" ]候補ディレクトリに通常のファイルがあることを確認します(nested use rh)。

rh -ref -- %Sうん、短縮rh -r -e f -- %S

-r検索と同様に、-mindepth 1 -maxdepth 11つのレベルを下回ってのみ検索できます。

一般ファイルに一致する検索基準式を指定します-e ff

悪意のあるファイル名が(たとえば)オプション--として解釈されるのを防ぐために、コマンドラインオプションの解析を停止します(Stéphaneに感謝します)。rh-xreboot

%Sネストが検索する必要がある現在の候補ディレクトリの名前。rh

[ -n ... ]ネストされたコマンドをテストすると、rhいくつかの出力が生成されます(つまり、候補ディレクトリでいくつかの一般的なファイルが見つかります)。

関連情報