ファイル名がディレクトリにない場合は、検索コマンド

ファイル名がディレクトリにない場合は、検索コマンド

特定のファイルなしでフォルダを表示する方法を知りたいです。ところで問題はファイル名は同じですが場合が違うということです。

ケース分析:toolsディレクトリの一部のサブディレクトリにはreadme/READMEファイルが含まれており、一部のサブディレクトリには含まれていません。例えば

/toola/readme
/toolb/README
/toolc/ (does not have readme file)

このコマンドを使用して、findコマンドを使用してtoolcフォルダのみを表示したいと思います。

find . -maxdepth 2 ! -name '*readme*' -o ! -name '*README*' | awk -F "/" '{print $$2}' | uniq

しかし、これはうまくいきません。toolaなしREADMEtoolbなしですべてのファイルを表示します。readme

ベストアンサー1

find存在しないファイルを見つけるためには使用できません。ただし、それを使用してfindディレクトリを見つけて、そのディレクトリに指定されたファイル名があるかどうかをテストできます。

findディレクトリ検索を使用するとき。を使用して-type d、見つかった各ディレクトリのファイルをテストしますREADMEreadme

いくつかの最上位ディレクトリに次のディレクトリ階層があるとしますprojects

projects/
|-- toola
|   |-- doc
|   |-- readme
|   `-- src
|-- toolb
|   |-- doc
|   `-- src
|-- toolc
|   |-- README
|   |-- doc
|   `-- src
`-- toold
    |-- doc
    `-- src

ファイルを含まない直下のディレクトリを見つけるために使用されますfindprojectsREADMEreadme

$ find projects -mindepth 1 -maxdepth 1 -type d \
    ! -exec test -f {}/README ';' \
    ! -exec test -f {}/readme ';' -print
projects/toolb
projects/toold

ここですぐ下のディレクトリを見つけて、projectsユーティリティtestを使用して、見つかったディレクトリのうち、これら2つのファイルのいずれも含まれていないディレクトリを確認します。

これはまさに次のとおりです。

find projects -mindepth 1 -maxdepth 1 -type d \
    -exec [ ! -f {}/README ] ';' \
    -exec [ ! -f {}/readme ] ';' -print

上記の別の表現は次のとおりです。

find projects -mindepth 1 -maxdepth 1 -type d -exec sh -c '
    for pathname do
        if [ ! -f "$pathname/README" ] &&
           [ ! -f "$pathname/readme" ]; then
            printf "%s\n" "$pathname"
        fi
    done' sh {} +

これには、実際にこれら2つのファイルをテストし、どちらも含まないディレクトリのパス名を印刷する小さなインラインシェルスクリプトがあります。このfindユーティリティは、インラインスクリプトが繰り返すことができるように、ディレクトリパス名の「パス名ジェネレータ」として機能します。

実際、ディレクトリ構造が次のような場合、findまったく使用しない可能性があります。

for pathname in projects/*/; do
    if [ ! -f "$pathname/README" ] &&
       [ ! -f "$pathname/readme" ]; then
        printf '%s\n' "$pathname"
    fi
done

パターンの末尾のスラッシュを参照してくださいprojects/*/。これは、パターンがディレクトリ(またはディレクトリへのシンボリックリンク)にのみ一致するようにすることです。

これを行うことと使用することの違いfindは、上記のシェルループを使用すると、下の隠しディレクトリを除いてprojectディレクトリへのシンボリックリンクが含まれることです。

いずれの場合も、ディレクトリのパス名を繰り返し、両方のファイル名が存在しないことをテストします。

唯一注目すべき点は、この-fテストが通常のファイルへのシンボリックリンクでも機能することです。

関連:

おすすめ記事