現在、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#./}
。コマンドの実行中にディレクトリ名が変更された場合は、より強力なので、
-execdir
代わりに使用してください。-exec
式では、
bash -c '...' mover {}
bashは一重引用符で囲まれ、ファイル名に割り当てられたコマンドを実行します$0
。シェルがエラーメッセージを作成する必要がない限り、使用されません。mover
$1
{}
$0
このコードにはbash機能は必要ありません。すべてのPOSIXシェルを使用できます。
コマンドを実行する前にテストして必要に応じて動作することを確認するには、
echo
次のように追加します。find . -maxdepth 2 -mindepth 2 -type d -execdir bash -c 'echo mv "$1" "./album_${1#./}"' mover {} \;
ガイドライン-exec mv '{}' album_'{}'
引用しないでください
{}
。find
指定されたファイル名が 。
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*/*