印刷フォルダに.txtファイル形式がありません。

印刷フォルダに.txtファイル形式がありません。

私の親ディレクトリには150のディレクトリがあります。それらのいくつかは.txt文書を持ち、他のものはそうではありません。ファイルのないフォルダを印刷したいです.txt。この目標をどのように達成できますか?

答え1

for dir in */; do
    set -- "$dir"/*.txt
    [ ! -e "$1" ] && printf '%s\n' "$dir"
done

これは現在のディレクトリのすべてのディレクトリを繰り返します。ディレクトリごとに、.txt位置set引数(、など)をパターンに一致するファイルのパス名$1に設定し、何も一致しない場合はパターン自体に設定します。このファイル名拡張の最初の結果が既存のファイルのパス名でない場合は、ディレクトリ名が印刷されます。$2$1


現在のディレクトリを含むすべてのディレクトリに対してこの操作を繰り返し実行するには、次の手順を実行します。

find . -type d -exec sh -c '
    for dir do
        set -- "$dir"/*.txt
        [ ! -e "$1" ] && printf "%s\n" "$dir"
    done' sh {} +

findこれはディレクトリパス名のジェネレータとして使用されます。まとめて見つかったディレクトリパス名に対して以前と同じループを実行して、含まれていない名前を印刷します.txt


上記の両方のコードは、次の項目の存在を検出します。どの名前はで終わります.txt。興味がある場合一般ファイル(または一般ファイルへのシンボリックリンク)以下をループ本体として使用します。

while [ "$#" -gt 0 ] && [ ! -f "$1" ]; do
    shift
done
[ ! -e "$1" ] && ...as above...

含む隠されたファイル名(withのbash -O dotglob -c代わりに使用するなど)これにより、シェルループのファイル名グロービングがドットで始まる名前も考慮されます。最初のバリエーションでは、ループを実行するときにシェルオプションを設定する必要があります。sh -cfinddotglobshopt -s dotglobbash

答え2

私は次の方法でこれを達成できました。

#!/bin/bash

search_dir=~/tmp

dirs=( $( find "$search_dir" -type f -name "*.txt" -exec dirname {} \; | sort -u ) )
exclude=()

for dir in "${dirs[@]}"; do
    exclude+=( -not -path "$dir" )
done

find "$search_dir" "${exclude[@]}"  -type d 

変数をsearch_dir使用する親ディレクトリに変更します。

次に、dirs各ディレクトリに配列を設定します。する.txt ファイルが含まれています。

excludeその後、各ディレクトリはに入力できる形式で配列に追加されますfind。次に、除外配列にないすべてのディレクトリに対して親ディレクトリを再度検索します。

関連情報