web-dev-qa-db-ja.com

ubuntu / bashの下でファイルとディレクトリの名前を再帰的に変更します

Wordを含むすべてのファイルとディレクトリの名前を「special」から「regular」に変更します。 「特殊」が「通常」にならないように、大文字と小文字の区別を維持する必要があります。

これをbashで再帰的に行うにはどうすればよいですか?

55
Tom

これを試してください(bash --version> = 4が必要):

shopt -s globstar
rename -n 's/special/regular/' **

テストに問題がなければ、-nスイッチを削除します

warning これを行うことができる場合とできない場合がある同じ名前の他のツールがありますので、注意してください。

次のコマンドを実行する場合(GNU

$ file "$(readlink -f "$(type -p rename)")"

そして、あなたは次のような結果を持っています

.../rename: Perl script, ASCII text executable

含まれていない:

ELF

その後、これは正しいツールのようです=)

そうでない場合、DebianおよびUbuntuのような派生物のデフォルト(通常はすでにそうです)にするために:

$ Sudo update-alternatives --set rename /path/to/rename

/path/to/renamePerl's renameコマンドのパスに置き換えます。


このコマンドがない場合は、パッケージマネージャーを検索してインストールするか、 手動で実行


最後になりましたが、このツールはもともとPerlの父であるLarry Wallによって書かれました。

74
Gilles Quenot

findを使用したソリューション:

名前を変更するにはファイルのみ

find /your/target/path/ -type f -exec rename 's/special/regular/' '{}' \;

名前を変更するにはディレクトリのみ

find /your/target/path/ -type d -execdir rename 's/special/regular/' '{}' \+

両方の名前を変更するにはファイルとディレクトリ

find /your/target/path/ -execdir rename 's/special/regular/' '{}' \+
94
speakr

別のツールをインストールしてもかまわない場合は、 rnm を使用できます。

rnm -rs '/special/regular/g' -dp -1 *

すべてのディレクトリ/サブディレクトリを通過します(-dp -1)およびspecialregularの名前に置き換えます。

6
Jahid

@ speakr's answer は私にとっての手がかりでした。

-execdirを使用してファイルとディレクトリの両方を変換する場合は、示されている例から-type fも削除する必要があります。それを綴るには、次を使用します:

find /your/target/path/ -execdir rename 's/special/regular/' '{}' \+

また、gの発生をallで置き換える場合は、special(グローバル)フラグを正規表現に追加することを検討してください。 regularは、最初の出現だけでなく、指定されたファイル名に含まれます。例えば:

find /your/target/path/ -execdir rename 's/special/regular/g' '{}' \+

special-special.jpgregular-regular.jpgに変換します。グローバルフラグがないと、regular-special.jpgになります。

参考:GNU Mac OSXではデフォルトで名前の変更はインストールされません。 Homebrewパッケージマネージャー を使用している場合、brew install renameは修復されますこの。

2
U007D

ディレクトリの名前を変更するだけの場合は、次のコマンドを使用できます。

find /your/target/path/ -type d -execdir rename 's/special/regular/' '{}' \;

注:タイプはディレクトリのdになり、-execdir

ただし、1回のパスでファイルとディレクトリの両方の名前を変更する方法を見つけることができませんでした。

ルートフォルダーの名前を変更すると、ファイルツリーを走査できなくなると以前にコメントしました。 -dスイッチは、ボトムアップから深さ方向のトラバースを行うため、ルートの名前が最後に変更されると信じています。

find -d /your/target/path/ -type d -execdir rename 's/special/regular/' '{}' \;

マンページから(man find):

 -d      Cause find to perform a depth-first traversal, i.e., directories are visited in post-order and all entries in a directory will be
         acted on before the directory itself.  By default, find visits directories in pre-order, i.e., before their contents.  Note, the
         default is not a breadth-first traversal.
0
LokMac

よりポータブルで、notrenameコマンドに依存する別のアプローチを示します(ディストリビューションによって異なるパラメーターが必要になる場合があるため)。

ファイルとディレクトリの名前を再帰的に変更します。

find . -depth -name "*special*" | \
while IFS= read -r ent; do mv $ent ${ent%special*}regular${ent##*special}; done

機能

  • findを-depthパラメーターとともに使用して、depth-first traversalを実行して結果を並べ替えます(つまり、ディレクトリ内のすべてのエントリがディレクトリの前に表示されます)自体)。
  • パス内で最後に出現したregularのみを変更するパターン置換を行います。

これにより、ファイルが最初に変更され、次に各親ディレクトリが変更されます。

次のツリーを与える:

├── aa-special-aa
│   └── bb-special
│       ├── special-cc
│       ├── special-dd
│       └── Special-ee
└── special-00

これらのmvコマンドを特定の順序で生成します。

mv ./aa-special-aa/bb-special/special-cc ./aa-special-aa/bb-special/regular-cc
mv ./aa-special-aa/bb-special/special-dd ./aa-special-aa/bb-special/regular-dd
mv ./aa-special-aa/bb-special ./aa-special-aa/bb-regular
mv ./aa-special-aa ./aa-regular-aa
mv ./special-00 ./regular-00

次のツリーを取得するには:

├── aa-regular-aa
│   └── bb-regular
│       ├── regular-cc
│       ├── regular-dd
│       └── Special-ee
└── regular-00
0
jyvet