同じディレクトリ内のファイル拡張子の検索を制限するには、find またはその他のコマンドを使用します。

同じディレクトリ内のファイル拡張子の検索を制限するには、find またはその他のコマンドを使用します。

複数のサブディレクトリがあるディレクトリがあります。サブディレクトリを1つずつ繰り返しています。次に、CDを使用してディレクトリを変更します。そのサブディレクトリに.partial拡張子を持つファイルがある場合は、ファイル名を保存します。次に、サブディレクトリ名とファイル名の一部を印刷する必要があります。私はこんなことを書いた。

for f in *
do
    if [ -d "$f" ]; then
        cd "$f"
        a=$(find ./ -name "*.partial")
        if [ -e "$a" ];then
            echo -e "$f" "\t" "$a"
        fi
        cd ..
    fi
done

find問題は、私が望ましくない追加のサブディレクトリでファイル拡張子を繰り返し見つけることです。.partial現在のディレクトリに限定するにはどうすればよいですか?

答え1

.partial現在のディレクトリに関連付けられている各ファイルのフルパス名のみを出力します。

printf '%s\n' ./*/*.partial

一致するものがない場合、nullglobシェルオプションを設定するとパターン自体は出力されず(空白行はまだ出力されます)、隠された名前も一致します。bashdotglob


以下は、これらのパス名をディレクトリパスとファイル名の部分に分割します。

for name in ./*/*.partial; do
    [ -f "$name" ] && printf '%s\t%s\n' "${name%/*}" "${name##*/}"
done

これにより、現在のディレクトリのサブディレクトリにある.partialすべての名前のサブディレクトリ名とファイル名が印刷されます。.partial

ではbash、隠された名前も一致させる必要がある場合は、シェルオプションを設定する必要があります。dotglob

dirnameこれら2つの引数の置換は、次のように呼び出すことによって実行できますbasename

for name in ./*/*.partial; do
    [ -f "$name" ] && printf '%s\t%s\n' "$(dirname "$name")" "$(basename "$name")"
done

サブディレクトリ名を一度だけ印刷する上記のバリエーションです(これを行うには、ディレクトリパスを削除して各場所引数のファイル名を保持するbashシェルなどの引数拡張が必要です)。${*%%*/}

IFS=$'\t'
for dirname in ./*/; do
    set -- "$dirname"/*.partial;
    [ -f "$1" ] && printf '%s\t%s\n' "$dirname" "${*##*/}"
done

これは各サブディレクトリを繰り返し、*.partial各サブディレクトリのワイルドカードパターンを拡張します。最初の一致が通常のファイル(またはファイルへのリンク)の場合は、サブディレクトリ名を印刷し、その後にパターンと一致する名前を印刷してディレクトリパスを削除します。

答え2

このfindユーティリティは次のオプションをサポートします。-maxdepth

-max 深さレベル
始点より下のディレクトリに降りる最も高いレベル(負でない整数)レベルです。 -maxlength 0 は、始点自体にのみテストと操作を適用することを意味します。

find特定のディレクトリに制限するには、optionsを追加してください-maxdepth 1


深さ2のすべての一般ファイルをリストしようとすると、出力は質問のものと*.partial似ています。次のコマンドを試すことができます。

 find . -mindepth 2 -maxdepth 2 -type f -name '*.partial' -printf '%h\t./%f\n'

これは次のような出力を提供できます。

./b    ./file2.partial
./b    ./file3.partial
./a    ./file1.partial

答え3

GNUがあれば、find次のようにすることができます

for dir in *
do
    files=$(find "$dir" -maxdepth 1 -type f -name '*.partial' -printf "%f\n" | xargs)
    [[ -n "$files" ]] && printf "%s\t%s\n" "$dir" "$files"
done

GNUがなければ、find効率を犠牲にして次のようにエミュレートできます。-printf '%f\n'

for dir in *
do
    files=$(cd "$dir" && find . -maxdepth 1 -type f -name '*.partial' -print | sed 's!^./!!' | xargs)
    [[ -n "$files" ]] && printf "%s\t%s\n" "$dir" "$files"
done

どちらのソリューションも、改行や奇妙な印刷文字を含むファイルを処理しません。しかし、ディレクトリ内のファイルを1行にリストすると、奇妙なファイル名が発生しないことを願っています。シェルがこれを理解していない場合は、[[ ... ]]二重括弧を単一の括弧に置き換えてください[ ... ]

関連情報