このコマンドを使用してファイル名を再帰的に変更します。
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
)です。
-iname
rename
とにかく、他の種類のファイル名のサフィックスの大文字にファイル名を変更しないので、大文字と小文字の区別の一致が不要なので、これをtestに変更しました-name
。また、名前に文字列を含むファイル(たとえば)が奇妙な方法で名前を変更しないように(たとえば、名前を変更する)、あなたのrename
呼び出しを修正しました。bak
rebak.bak
r.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
また、シンボリックリンクの名前が通常のファイルに変更されます。
答え2
この試み
find -iname \*.bak -not -path "./.bak" | rename 's/.bak/.old/'