より多くのユーザーのtmp
ホームディレクトリにディレクトリがあるとします。tmp
すべてのユーザーのホームディレクトリにあるすべてのディレクトリの名前を変更したいと思います。最も簡単な方法は何ですか?
このような:
sudo mv /home/*/tmp /home/*/temp
いいえ。
このような:
for dir in /home/*; do
if [ -d $dir/tmp ]; then
mv $dir/tmp $dir/temp
fi
done
あまりにも多いようです。
答え1
Perl は、rename(1)
ほとんどの Linux システムにインストールされたコマンドとともに提供されます。 Debian ベースのシステムでは、/usr/bin
この場合は次のように使用できます。
$ rename 's/tmp$/temp/' /home/*/tmp
最初のパラメータは、新しい名前の後続のパラメータを生成するために使用されるPerl式です。その後、その式の結果に応じてそれぞれの名前が変更されます。
ホームディレクトリにすでに名前が付けられているファイル/ディレクトリがある場合は、temp
そのディレクトリにのみエラーが発生して続行しrename
ます。
/home/c/tmp not renamed: /home/c/temp already exists
まず、そのフラグを使用して実行して、-n
実際に実行せずに名前変更が実行する操作を確認し、すべてが正しく表示されていることを確認できます。それからそれを置き、-n
私の役割を果たしてください。
答え2
sudo find /home -maxdepth 2 -type d -name 'tmp' -execdir mv {} temp \;
ここでは、maxdepth
現在のディレクトリで最大2つのレベルのみを見つける必要があります。また、execdir
見つかったファイルの場所を変更して後続のコマンドを実行するように指定します。
答え3
質問の2番目のオプションを短縮するために私が考えることができる唯一の方法は次のとおりです。
for dir in /home/*;do
[ -d $dir/tmp ] && mv -n $dir/t{,e}mp
done
しかし、これは可読性をある程度減少させる。はt{,e}mp
シェルによって2つの単語tmp
に展開されますtemp
。したがって、コマンドラインはに展開されますmv <contents of $dir>/tmp <contents of $dir>/temp
。通常、シェルはprefix_{a,b,c}_suffix
に展開されますprefix_a_suffix prefix_b_suffix prefix_c_suffix
。空の位置(たとえば、の最初の位置)は空の{,e}
文字列に展開されます。
次のこともできますperl
。
perl -e '
@a=grep {-d} glob "/home/*/tmp";
map { rename $_ => $_=~ s/tmp\Z/temp" } @a
'
しかし、私はまだ元のバージョンで十分だと思います。
編集する
この問題に関するMichael Kjörlingのコメントで述べたように、スイッチが存在する場合にクラッシュしないようにするために-n
スイッチが追加されました。パールバージョンmv
$dir/temp
〜するtemp
存在する場合は破棄します。
答え4
移動ステートメントを生成し、一度にすべて評価します。
ls -d /home/*/tmp | sed 's/.*t/mv &mp &e/' | sh -xv