すべてのユーザーアカウントのディレクトリ名を変更する方法

すべてのユーザーアカウントのディレクトリ名を変更する方法

より多くのユーザーの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見つかったファイルの場所を変更して後続のコマンドを実行するように指定します。

源泉:https://stackoverflow.com/a/15007149/147021

答え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

関連情報