複数のサブディレクトリがあるディレクトリがあります。サブディレクトリを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
シェルオプションを設定するとパターン自体は出力されず(空白行はまだ出力されます)、隠された名前も一致します。bash
dotglob
以下は、これらのパス名をディレクトリパスとファイル名の部分に分割します。
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行にリストすると、奇妙なファイル名が発生しないことを願っています。シェルがこれを理解していない場合は、[[ ... ]]
二重括弧を単一の括弧に置き換えてください[ ... ]
。