web-dev-qa-db-ja.com

Linuxでファイルを再帰的に名前変更(拡張子を変更)

数千のサブフォルダにある数千のファイルについて、ディレクトリ内のすべてのファイルの名前を再帰的に変更して、ファイル拡張子を別の拡張子に変更するにはどうすればよいですか?ほとんど私が望んでいることを実行するコマンドがたくさんありますが、完全ではありません。

find . -name "*.andnav" -exec rename .andnav .tile {} \;
syntax error at (eval 1) line 1, near "."

...

rename -nv 's/\.andnav$/\.tile/i' *.andnav
0.png.andnav renamed as 0.png.tile
24
endolith

理解した

find . -name "*.andnav" -exec rename -v 's/\.andnav$/\.tile/i' {} \;
./0/0.png.andnav renamed as ./0/0.png.tile
./0/1.png.andnav renamed as ./0/1.png.tile
./1/0.png.andnav renamed as ./1/0.png.tile
./1/1.png.andnav renamed as ./1/1.png.tile

もちろん、実際に実行するときに-vを削除してください。削除しないと、すべてのファイルの表示に時間がかかります。

29
endolith

Zshの場合:

autoload zmv
zmv -n '(**/)(*).andnav' '$1$2.tile'

-nを削除して、実際に名前変更を実行します。

何かのようなもの:

find . -name '*.andnav' -exec sh -c 'mv "$0" "${0%.andnav}.tile"' {} \;

説明

上記は、現在の作業ディレクトリ(.)からディレクトリツリーのウォークを開始します。ファイル名がパターン*.andnav(たとえば、foo.andnav)に一致するたびに、次のコマンドが実行されます。

sh -c 'mv "$0" "${0%.andnav}.tile"' foo.andnav

ここで、$0foo.andnavであり、${0%.andnav}.tile.andnav接尾辞を.tileに置き換えます。したがって、基本的に:

mv foo.andnav foo.tile
15
cYrus

この方法の方がどんどん読みやすくなっていることがわかりました。

find . -name "*.andnav" | rename "s/\.andnav$/.tile/"

コマンドラインに何もない場合、少なくともUbuntu派生では、renameはSTDINからファイルのリストを取得します。そして、これは以下で簡単にテストできます:

find . -name "*.andnav" | rename -vn "s/\.andnav$/.tile/"

あなたがそれを正しくするまで。

4
Bernd Wechner

findを再帰的に使用:

  • 次の例では、「foo」は「bar」に置き換えられます。
  • 検索パラメータをより詳細に制御するには、-name fooを追加して、特定のインスタンスのみの名前を変更します。 find . -depth -name foo -type d -execdir rename "s/foo/bar/" \{} \+。これを使用すると、より高速な検索も実行されます。
  • グローバルgフラグは、文字列内のすべての出現を置き換えます。それがなければ、最初の出現のみが置き換えられます。
  • 大文字と小文字を区別しないiフラグは、大文字と小文字を区別しない置換を実行します。大文字と小文字を区別しない検索では、-inameの代わりに-nameを使用します。
  • ワイルドカード*は、特定の操作で必要に応じて使用されます。
  • 詳細な-vトリガーが含まれており、進行状況を表示できます。含まれていない場合、シェルがプロンプトに戻るとコマンドは完了です。
  • アクション-nトリガーはプロセスをシミュレートしません。印刷結果に満足したら削除します。

例1:

find /target/path/ -depth -type d -name "foo*" -execdir rename -v -n "s/foo/bar/g" \{} \+

例2:

find -execdir rename "s/foo/bar/" \{} \;

すべてのファイル/ディレクトリの名前を変更します

find ./ -depth -execdir rename -v -n "s/foo/bar/gi" \{} \+

すべてのファイルのみの名前を変更

find ./ -type f -execdir rename -v -n "s/foo/bar/gi" \{} \;

特定の拡張子を持つすべてのファイルの名前を変更します

find ./ -type f -iname "*foo*.txt" -execdir rename -v -n "s/foo/bar/gi" \{} \;

すべての名前を変更ディレクトリのみ

find ./ -depth -type d -execdir rename -v -n "s/foo/bar/gi" \{} \+

文字列内の単語全体の名前を変更:

find ./ -depth -name "* foo *" -execdir rename -v -n "s/foo/bar/g" \{} \+

または;

find ./ -depth -execdir rename -v -n "s/* foo */ bar /g" \{} \+

OPに従って:

find ./ -type f -name "*.andnav" -execdir rename -v -n "s/andnav/tile/" \{} \;


findコマンドに関する有用な記事: https://www.tecmint.com/35-practical-examples-of-linux-find-command/comment-page-4/#comments =

0
Reactive

あなたがzshシェルを持っているなら、これは満足です:

rename -n -e 'EXPRESSION_HERE' **/*

削除する -n動作します。

0
Ivan Gonzalez