web-dev-qa-db-ja.com

最後の文字「_」を検索して「。」に置き換えますファイル名を再帰的に

「破損した」名前で保存された数百万のファイルがあります。拡張機能は_pdfとして保存されました。

私が欲しいのは、再帰的に、すべての拡張機能を編集して、期待どおりにドットを使用することです。

find . -name '*_pdf' -type f -exec bash -c 'mv -- "$1" "${1//_/.}"' -- {} \;

私はすでにこのbashスクリプトで試しましたが、作成されたすべての '_'を '。'で置き換えます。共通の拡張子(pdf、jpg、jpeg)が付いている場合は、最後の_だけが必要です。

4
JoseSilva

_はグローバルであるため、${1//_/.}のすべてのインスタンスが置き換えられます(${1/_/.}はグローバルではありませんが、最後ではなくfirstを置き換えます)。

代わりに、POSIX ${1%_*}および${1##*_}を使用して、最短のサフィックスと最長のプレフィックスを削除してから、それらを再結合できます。

find . -name '*_pdf' -type f -exec sh -c 'mv "$1" "${1%_*}.${1##*_}"' sh {} \;

または

find . -name '*_pdf' -type f -exec sh -c 'for f do mv "$f" "${f%_*}.${f##*_}"; done' sh {} +

複数の拡張子の場合:

find . \( -name '*_pdf' -o -name '*_jpg' -o -name '*_jpeg' \) -type f -exec sh -c '
  for f do mv "$f" "${f%_*}.${f##*_}"; done
' sh {} +

--オプション終了区切り文字を削除しました-findは名前の前に./を付けているため、ここでは必要ありません。

特定のディレクトリに-ifile_pdfの両方が存在する可能性があり、チャンスを与えたくない場合は、file.pdfオプションをmvに追加することができます。既存のfile.pdfを破壊します。

13
steeldriver

Perl renameツールを使用:

find ... rename 's/_pdf$/.pdf/' {} +

異なる拡張機能に対して個別に実行することも、複数の「共通拡張機能」を一度に置き換えることもできます。

find ... rename 's/_(pdf|jpg|jpeg)$/.\1/' {} +

Perlの名前変更がない場合は、他の renameツール を使用できます。

find ... rename '_pdf' '.pdf' {} +
7
pLumo