すべてのディレクトリに対して - プレフィックスを使用して、すべてのサブディレクトリの名前を変更します。

すべてのディレクトリに対して - プレフィックスを使用して、すべてのサブディレクトリの名前を変更します。

現在、2000のユーザーディレクトリがあり、各ディレクトリにはサブディレクトリがあります。

ユーザー_1

--->サブ1

--->子供2

ユーザー_29

--->子供37

--->子供56

など

すべてのユーザーフォルダと各サブフォルダを繰り返し、プレフィックス "album_"を使用してサブフォルダの名前を変更する必要があります。私の最終構造は次のようになります。

ユーザー_1

--->アルバム_子供1

--->アルバム_子供2

ユーザー_29

--->アルバム_child37

--->アルバム_child56

以下を使用して、ユーザーフォルダの名前を変更できます。

for f in * ; do mv "$f" user_"$f" ; done;

私は次のようにサブディレクトリの名前を変更するいくつかの異なる方法を試してきました。

find . -maxdepth 2 -mindepth 2 -type d -exec mv '{}' album_'{}'

上記のクエリの最初の部分は、名前を変更する必要があるすべてのディレクトリを返します( 'find . -max深度2 -min深さ2 -type d')。

-exec関数でディレクトリ名にアクセスしてプレフィックスを付けるにはどうすればよいですか?

答え1

努力する:

find . -maxdepth 2 -mindepth 2 -type d -execdir bash -c 'mv "$1" "./album_${1#./}"' mover {} \;

メモ:

  1. ./宛先ディレクトリの名前を設定するには、ディレクトリ名から最初の文字を削除する必要があります。これを達成するために、我々はシェルのプレフィックスの削除${1#./}

  2. コマンドの実行中にディレクトリ名が変更された場合は、より強力なので、-execdir代わりに使用してください。-exec

  3. 式では、bash -c '...' mover {}bashは一重引用符で囲まれ、ファイル名に割り当てられたコマンドを実行します$0。シェルがエラーメッセージを作成する必要がない限り、使用されません。mover$1{}$0

  4. このコードにはbash機能は必要ありません。すべてのPOSIXシェルを使用できます。

  5. コマンドを実行する前にテストして必要に応じて動作することを確認するには、echo次のように追加します。

    find . -maxdepth 2 -mindepth 2 -type d -execdir bash -c 'echo mv "$1" "./album_${1#./}"' mover {} \;
    

ガイドライン-exec mv '{}' album_'{}'

  1. 引用しないでください{}find

  2. 指定されたファイル名が 。findで始まるので、./フォームはalbum_{}成功しません。

はい

次のディレクトリを考えてみましょう。

$ ls *
user1:
child1  child2

user2:
child1  child2
Press any key to continue...

今。コマンドを実行し、新しいディレクトリ名を確認してみましょう。

$ find . -maxdepth 2 -mindepth 2 -type d -execdir bash -c 'mv "$1" "./album_${1#./}"' mover {} \;
$ ls *
user1:
album_child1  album_child2

user2:
album_child1  album_child2

答え2

perl基本になったらrename

find -maxdepth 2 -mindepth 2 -type d -exec rename -n 's|.*/\K|album_|' {} +
  • .*//ディレクトリパスの最後のエントリと一致します。
  • Lookbehindを使用すると、\Kこの場合はキャプチャグループが不要になる可能性があります。
  • デフォルトでは、inは.現在のディレクトリに適用されるため、スキップできます。find .find

-n正しい名前変更が表示されたら、名前変更からオプションを削除します。

例:

$ ls *
user_1:
child1  child2

user_29:
child37  child56

$ find -maxdepth 2 -mindepth 2 -type d -exec rename -n 's|.*/\K|album_|' {} +
rename(./user_29/child37, ./user_29/album_child37)
rename(./user_29/child56, ./user_29/album_child56)
rename(./user_1/child2, ./user_1/album_child2)
rename(./user_1/child1, ./user_1/album_child1)
$ find -maxdepth 2 -mindepth 2 -type d -exec rename 's|.*/\K|album_|' {} +

$ ls *
user_1:
album_child1  album_child2

user_29:
album_child37  album_child56

答え3

私は通常 -exec を直接使用しません。問題が発生した場合、デバッグが難しくなるためです。find実行する前に確認できるスクリプトを作成してください。

find . -maxdepth 2 -mindepth 2 -type d -printf 'mv "%P" "%h/album_%f"\n' > /tmp/rename.sh sh /tmp/rename.sh

答え4

Perlベースの名前変更をインストールすると

rename 's!(.*/)!$1album_! if(-d $_)' user*/*

関連情報