再帰的な名前変更は現在のディレクトリを除外します。

再帰的な名前変更は現在のディレクトリを除外します。

このコマンドを使用してファイル名を再帰的に変更します。

find -iname \*.bak | rename 's/.bak/.old/'

しかし、現在のディレクトリを除外したいと思います。例:

.bak
dir1/.bak
dir2/.bak
...

私はこれが欲しい:

.bak
dir1/.old
dir2/.old
...

ベストアンサー1

find述語サポートと一緒にaを使用してください-mindepth

 find . -mindepth 2 -type f -name '*.bak' | rename 's/\.bak$/.old/'

述語を使用すると、-mindepth一致が発生する可能性がある最小検索深度を定義できます。深さ0はルート検索パス自体(.)、深さ1はルート検索パスの直下にある項目(たとえば)、./somename深さ2はルート検索パスのすぐ下にある項目(たとえば./somename/other)です。

-inamerenameとにかく、他の種類のファイル名のサフィックスの大文字にファイル名を変更しないので、大文字と小文字の区別の一致が不要なので、これをtestに変更しました-name。また、名前に文字列を含むファイル(たとえば)が奇妙な方法で名前を変更しないように(たとえば、名前を変更する)、あなたのrename呼び出しを修正しました。bakrebak.bakr.old.bak

-type fまた、一般ファイルだけがfind考慮されるという点、つまりディレクトリなどは考慮されないと付け加えました。

より移植性の高いソリューションの場合:

find . -mindepth 2 -type f -name '*.bak' -exec sh -c '
    for pathname do
        mv "$pathname" "${pathname%.bak}.old"
    done' sh {} +

これはユーティリティに依存しませんrename

find . -mindepth 2 -type f -name '*.bak' -exec rename 's/\.bak$/.old/' {} +

これはrename通貨から直接来たものですfind

関連:


を使用すると、完全にスキップし、次のことがbashできます。find

shopt -s globstar dotglob

rename 's/\.bak$/.old/' ./*/**/*.bak

ワイルドカードパターンは、**任意の数の中間サブディレクトリと一致します。この特殊モードはglobstarシェルオプションで有効になります。最初は、./*/現在のディレクトリ自体ではなく、現在のディレクトリのサブディレクトリのみを見つけることを保証します。

シェルdotglobオプションを使用すると、隠された名前をパターンと一致させることができます。

ただし、上記のコマンドは通常のファイルを特に選択しません(ただし、ユーザーコマンドfindも同じです)。これを行うには、ループを使用してください。

shopt -s globstar dotglob

for pathname in ./*/**/*.bak; do
    [[ ! -f $pathname ]] && continue
    rename 's/\.bak$/.old/' "$pathname"
done

また、シンボリックリンクの名前が通常のファイルに変更されます。

おすすめ記事