
たくさんのフォルダがあり、それらすべてのフォルダをループして、各フォルダに「写真」という名前の別のフォルダを作成したいです。
F1
--F11
----F111
----F112
--F12
私が欲しいのは:
F1
--Photo
--F11
----Photo
----F111
------Photo
----F112
------Photo
--F12
----Photo
答え1
1 回の呼び出しで実現できますfind
。
find . -name 'Photo' -prune -o -type d -exec mkdir {}/Photo \;
この部分は-name 'Photo' -prune -o
、既存の(および新しく作成された)ディレクトリに再帰しないように指示しますPhoto
。見つかったファイル(またはディレクトリ)の名前が の場合Photo
、処理を停止します(-prune
)。それ以外の場合(-o
)は、ディレクトリ(-type d
)を続行し、-exec
コマンドを実行します( )。
答え2
代わりfind
に結果を渡すこともできます。こうすることで、ファイル名にスペースが含まれていても壊れません。while
for
まずディレクトリに cd してF1
、次の操作を実行します。
find -type d | while read dir ; do mkdir "$dir"/Photo ; done
ディレクトリが存在する場合は、mkdir
作成を拒否するだけなので、問題はありません...
ディレクトリ名に改行文字やその他の奇妙な文字が含まれる可能性がある場合は、任意の名前を処理できる次のものを使用してください。
find -type d -print0 | while IFS= read -r -d '' dir ; do mkdir "$dir"/Photo ; done
この件について助けてくれた @terdon に感謝します :)
答え3
F1 のすぐ上のディレクトリから次のスクリプトを実行します。
このスクリプトの目的は、写真ディレクトリの下に冗長な写真ディレクトリが作成されないようにすることです。
また、ユーザーのルート ディレクトリなどの間違った場所から誤って実行することを防ぐように設計されていますが、ディレクトリが認識されずF1
、間違った場所に何百もの写真ディレクトリが誤って作成されることはありません。
また、ユーザーがカスタマイズできるように、わかりやすいスクリプトを作成することも私の意図でした。
#!/bin/bash
while IFS= read -r -d '' i;
do
if [[ ! -d $i/Photo ]]; then
# Filter to skip folders named Photo
thisfolder="$(echo $i | sed "s/.*\///")"
if [[ ! $thisfolder == "Photo" ]]; then
mkdir "$i/Photo"
fi
fi
done < <(find F1 -type d -print0)
スクリプトが更新されました:
- 小文字を大文字に変更しまし
p
たphoto
。 - 非標準ファイル名のサポートを追加しました (Terdon からの提案による)。
答え4
bash を使用している場合は、次のコマンドを実行するだけです:
shopt -s globstar
for d in **/; do mkdir -p "$d"/Photo; done
オプションglobstar
は、**
「すべてのファイルと 0 個以上のディレクトリとサブディレクトリ」に一致します。言い換えると、すべてを再帰的に一致させます。/
末尾の により、**/
はすべてのディレクトリとサブディレクトリ (ファイルなし) に一致します。したがって、 は$d
現在のディレクトリとそのサブディレクトリ内のすべてのディレクトリを反復処理し、Photos
それぞれのディレクトリにディレクトリが作成されます。
旗-p
のmkdir
意味:
-p, --parents
no error if existing, make parent directories as needed
ここでは、ターゲット ディレクトリが既に存在する場合にエラー メッセージを抑制するために使用しています。エラーを表示する場合は削除してください。
Photo
ターゲットディレクトリにサブディレクトリを作成すると失敗することに注意してください。ファイルPhoto という名前です。ただし、このような場合に何をすべきかは指定されておらず、これまでに投稿された他のすべての回答にもこの制限があります。