しぐまろぐ

勉強したことや読んだ本について書きます。

renameコマンドでファイル・ディレクトリ名を再帰的に一括置換する

前提

環境:Ubuntu 18.04

やりたいこと

ファイル名・ディレクトリ名の一部を再帰的に置き換えたい。

現状

$ tree . 
.
├── 20201225.txt
└──dir1/
     ├── dir2/
     │   ├── dir3/
     │   │   └── 20201225.log
     │   └── dir4/
     │       └── backup_20201225.dump
     └── 20201225/

上記のうち、「20201225」部分を「20201226」に一括置換したい。
mvで1個ずつ置換するのも面倒なので、renameコマンドを使ってみる。

renameコマンド

書式は以下の通り。

rename [オプション] 's/[変換前文字列]/[変換後文字列]/' [対象ファイル]

CentOSUbuntuでパラメータ指定方法が異なるらしい。詳細は「参考」の1.を参照。


renameコマンドだけでは、カレントディレクトリ直下しか置き換えられない。

$ rename 's/20201225/20201226/'
$ tree . 
.
├── 20201226.txt
└──dir1/
     ├── dir2/
     │   ├── dir3/
     │   │   └── 20201225.log
     │   └── dir4/
     │       └── backup_20201225.dump
     └── 20201225/

そこで、findで条件に一致するファイルをすべて探し、
その結果をxargsに与え、xargsにrenameを実行してもらう。

結果

$ find . -name '*20201225*' | xargs rename 's/20201225/20201226/'
$ tree . 
.
├── 20201226.txt
└──dir1/
     ├── dir2/
     │   ├── dir3/
     │   │   └── 20201226.log
     │   └── dir4/
     │       └── backup_20201226.dump
     └── 20201226/

なお今回は、ファイルもディレクトリも置換対象としているが、
例えばファイルだけしか置換したくない場合は、
「find . -type -f -a -name '*20201225*'」とする。