63

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

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

4

8 に答える 8

113

を使用したソリューション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/' '{}' \+
于 2013-02-21T21:42:39.627 に答える
88

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

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

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

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

次のコマンドを実行した場合(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/rename(コマンドのパスに置き換えますperl's rename


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


最後になりましたが、このツールは元々、Perlのお父さんであるLarryWallによって作成されました。

于 2013-02-21T21:34:49.363 に答える
7

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

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

すべてのディレクトリ/サブディレクトリ(のため)を通過し、名前がspecialからregular-dp -1に置き換えられます。

于 2016-05-07T09:33:53.033 に答える
5

@speakrの答えは私にとっての手がかりでした。

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

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

また、最初のオカレンスだけでなく、特定のファイル名内のすべてのオカレンスをで置き換えるg場合は、正規表現に(グローバル)フラグを追加することを検討してください。例えば:specialregular

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

に変換special-special.jpgされregular-regular.jpgます。グローバルフラグがないと、最終的にはになりますregular-special.jpg

参考:GNURenameはデフォルトではMacOSXにインストールされていません。Homebrewパッケージマネージャーを使用している場合は、brew install renameこれを修正します。

于 2017-05-13T17:08:22.157 に答える
3

これは、より移植性が高く、コマンドに依存しない別のアプローチですrename(ディストリビューションによっては異なるパラメーターが必要になる場合があるため)。

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

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

それが何をするか

  • find with-depthパラメーターを使用して、深さ優先走査を実行して結果を並べ替えます(つまり、ディレクトリー内のすべてのエントリーがディレクトリー自体の前に表示されます)。
  • パス内のレギュラーの最後の出現のみを変更するためにパターン置換を実行します。

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

次の木を与える:

├── 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
于 2018-12-11T23:54:40.083 に答える
3

Rui Seixas Monteiroが述べたように、Findコマンドで-iregexパターンオプションを使用するのが最善です。次の作品を見つけました。U007Dで言及されているように、正規表現にグローバルフラグが含まれています。

ファイル:

find / path / -type f-iregex'。*special。*'-execdirrename's / special / regular / g''{}' \ +;

ディレクトリ:

find / path / -type d-iregex'。*special。*'-execdirrename's / special / regular / g''{}' \ +;

ファイルとディレクトリ

find / path /-iregex'。*special。*'-execdirrename's / special / regular / g''{}' \ +;
于 2020-04-07T20:43:53.963 に答える
2

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

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.
于 2017-02-11T04:31:15.033 に答える
1

renameバージョンではrename from util-linux 2.23.2、次のコマンドが機能しました。

find . -type f -exec rename mariadb mariadb-proxy '{}' \;

于 2019-12-03T15:09:37.800 に答える