すべてのディレクトリ内にフォルダ「写真」を再帰的に作成します


9

たくさんのフォルダがあり、それらすべてのフォルダをループして、各フォルダに「Photo」という名前の別のフォルダを作成したい

F1
--F11
----F111
----F112
--F12

欲しい:

F1
--Photo
--F11
----Photo
----F111
------Photo
----F112
------Photo
--F12
----Photo

回答:


8

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からの提案付き)。

1
lsの解析は絶対に避けます。異常な方法で失敗する可能性があります。これを避けた方が安全だと思います。
Arronical 2016

3
@Arronical lsは解析されません。これはユーザーへのフィードバックにすぎません...何が起こっているかを示しています。「これは写真のディレクトリです」という言葉と同じです。そこにディレクトリが作成されない理由をユーザーに知らせています。
LDジェームズ

1
私はそれが何が行われているかを見ることができなかったので、それが事実であるかもしれないと思っていました。その場合、私はコメントを撤回して傾斜を外します:)
Arronical

find -type d F1、 多分?
OlivierGrégoire2016

と呼ばれる(ディレクトリではなく)ファイルがある場合、これは失敗します$i/Photoが、OPはそのような場合に何をすべきかを指定していません。また、$isの1つに改行が含まれている、確かにありそうもないケースでも失敗します。
terdon 2016

24

1回のfind呼び出しで実現できます。

find . -name 'Photo' -prune -o -type d -exec mkdir {}/Photo \;

この部分-name 'Photo' -prune -oは、既存の(および新しく作成された)Photoディレクトリーに再帰しないように指示します。見つかったファイル(またはディレクトリー)の名前がのPhoto場合は、その処理を停止します(-prune)。それ以外の場合(-o)は、ディレクトリを続け-type d-exec)、コマンドを実行()します。


ああいい、私はそのようにそれを試してみました、そして私が間違っていたところがあなたの答えからわかります:)
Zanna

@Zanna -prune?:)はい、それはかなり直感に反していますが、学ぶ価値があります。
Melebius 2016

「写真」という名前のファイルが存在する場合、「写真」フォルダの作成を停止しますか?
Anwar

3
@Anwar現在のバージョンになります。要件にグレーゾーンがあります。:) beforeと-type d一緒に指定することでこれを変更できます。-name 'Photo'-prune
Melebius 2016

2
@Anwar一見しただけでは意味がありません。同じフォルダ内に通常のファイルと同じ名前のフォルダを作成することはできません。そしてfind、他のフォルダー(そのフォルダーのサブフォルダーを含め、必要な場合)を続行します。
Melebius 2016

9

の代わりにfind結果を渡すことができますwhileforこのようにファイル名にスペースが含まれていても壊れないのでます

まずディレクトリF1にcdし、次に次のようにします。

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に感謝します:)


opのF1ディレクトリがの場合、~user/Pictures親ディレクトリに移動して行を実行するとPhoto、彼のスペース内のすべてのディレクトリにディレクトリが配置されます。F1簡単に間違いを犯さないように、コマンドラインの一部としてを追加することを検討してください。そうすれば、誤って間違った場所から実行されても、ディレクトリは作成されません。
LDジェームズ

ええ、私は実際にはディレクトリ構造がわかりませんでした。F1代わりに、@ LDJames から編集することをお勧めします
Zanna

5

Pythonはos.walkかなり簡単に、数行のコードでそれを行うことができます

$ mkdir dir_one dir_two
$ mkdir dir_two/dir_three
$ python -c 'import os;[os.mkdir(r + "/Pictures") for r,d,f in os.walk(".")]'                 
$ tree
.
├── dir_one
│   └── Pictures
├── dir_two
│   ├── dir_three
│   │   └── Pictures
│   └── Pictures
└── Pictures

説明

私たちが扱っているのは次のコマンドです:python -c 'import os; [os.mkdir(r + "/ Pictures")for r、d、f in os.walk( "。")]'

ここでは、-cフラグを指定してpythonインタープリターを呼び出し、単一引用符で囲んだコマンドを指定しています。os.walk()関数を使用すると、すべてのサブディレクトリを再帰的にたどることができます。各サブディレクトリ(で表されますr)に対して、次のようにしてピクチャフォルダを作成します。os.mkdir()関数ます。r+"/Pictures"サブディレクトリ文字列と "/ Pictures"文字列を結合して1つのパスを形成する単純な文字列操作です

「/ Pictures」を「/ Photo」に置き換えて、要件に合わせます


4

bashを使用している場合は、次のコマンドを実行するだけです。

shopt -s globstar
for d in **/; do mkdir -p "$d"/Photo; done

このglobstarオプションは、**「すべてのファイルと0個以上のディレクトリとサブディレクトリ」を一致させます。つまり、すべてを再帰的に照合します。/最後に**/があるため、すべてのディレクトリとサブディレクトリに一致します(ファイルなし)。したがって、は$d現在のディレクトリとそのサブディレクトリ内のすべてのディレクトリを反復処理し、それぞれにディレクトリPhotosが作成されます。

-pmkdir手段:

  -p, --parents
          no error if existing, make parent directories as needed

ここでは、ターゲットディレクトリが既に存在する場合に、エラーメッセージを抑制するために使用しています。エラーを見たい場合は削除してください。

これPhotoは、Photoという名前のファイルを含むターゲットディレクトリにサブディレクトリを作成できないことに注意してください。それらの場合に何をすべきかを指定していませんが、これまでに投稿された他のすべての回答にもこの制限があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.