「special」という単語を含むすべてのファイルとディレクトリの名前を「regular」に変更したいと思います。「特殊」が「通常」にならないように、大文字と小文字の区別を維持する必要があります。
これをbashで再帰的に行うにはどうすればよいですか?
を使用したソリューション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/' '{}' \+
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によって作成されました。
別のツールをインストールしてもかまわない場合は、rnmを使用できます。
rnm -rs '/special/regular/g' -dp -1 *
すべてのディレクトリ/サブディレクトリ(のため)を通過し、名前がspecialからregular-dp -1
に置き換えられます。
@speakrの答えは私にとっての手がかりでした。
-execdirを使用してファイルとディレクトリの両方を変換する場合は-type f
、示されている例からも削除する必要があります。それを詳しく説明するには、次を使用します。
find /your/target/path/ -execdir rename 's/special/regular/' '{}' \+
また、最初のオカレンスだけでなく、特定のファイル名内のすべてのオカレンスをで置き換えるg
場合は、正規表現に(グローバル)フラグを追加することを検討してください。例えば:special
regular
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
これを修正します。
これは、より移植性が高く、コマンドに依存しない別のアプローチですrename
(ディストリビューションによっては異なるパラメーターが必要になる場合があるため)。
ファイルとディレクトリの名前を再帰的に変更します。
find . -depth -name "*special*" | \
while IFS= read -r ent; do mv $ent ${ent%special*}regular${ent##*special}; done
それが何をするか
-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
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''{}' \ +;
ディレクトリの名前を変更したいだけの場合は、次のコマンドを使用できます。
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.
rename
バージョンではrename from util-linux 2.23.2
、次のコマンドが機能しました。
find . -type f -exec rename mariadb mariadb-proxy '{}' \;