ファイル名から特定の文字を削除する

ファイル名から特定の文字を削除する

これについては少ししか理解していません。以下のコマンドは、すべてのファイル名からスペースを削除します。

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

 カンマ、ピリオド、括弧 ( 、  ,、  .、  )も削除したいのです  が、削除したい文字をコマンドのどこに配置すればよいかわかりません( 。 )

答え1

簡単に答えると、ファイル名からスペース、カンマ、ピリオド、括弧を削除するコマンドは(  $0)です。

mv "$0" "${0//[ ,.()]/}"

しかし、それを使わないでください...

より長い答え:

  • コマンドfindは です-name "* *.*"。これは、名前に少なくとも1つのスペースが含まれるファイルを選択します。 少なくとも 1 つのピリオドが続きます。  名前にスペースが含まれていないファイルを処理しようとしないのは理にかなっています。スペースがなければ削除するものがないからです。しかし、そのコマンドがなぜピリオドをテストするのかわかりません。名前はfat cat.txtに変更されますfatcat.txtが、hot dogと はfrank.fur terそのまま残ります。

    ファイル名にピリオドが含まれているファイルの名前を変更する (ピリオドを削除する) には、-nameテストを に 変更する必要があります-name "*[ ,.()]*"

  • 事前にわからないファイル名を扱う場合は、 --最初のファイル名の前に を置くのが最適です。 を実行するときにこれが厳密に必要というわけではありませんfind . … -exec …が、身につけておくとよい習慣です。

  • fat cat.txtおよびというファイルがある場合f a t c a t.txt、両方の名前が に変更されfatcat.txt、2 番目のファイルによって最初のファイルが上書きされます。 に-n(no-clobber) オプションを渡すmv と、これを防ぐことができます。ただし、注意してください。ファイル名にスペース (など) が含まれたままになり、問題が発生したことが通知されない場合もあります。

  • 現在のコマンドは、ファイルごとに新しいbashプロセスを呼び出します。これにより、必要以上に時間がかかる可能性があります。1bash回呼び出してからmv複数回呼び出すのが望ましいです。したがって、上記のすべてを組み込むと、

    find . -type f -name "*[ ,.()]*" -exec bash -c 'mv -n -- "$1" "${1//[ ,.()/}"' sh {} +
    

    でも待ってください! まだ終わりではありません! 上記のものは使用しないでください。

  • findがコマンド ( を使用) を実行する と-exec、ファイルへのパス名がコマンドに渡されます。fat cat.txt現在のディレクトリに というファイルがある場合、 はbash コマンドにfind渡されます。上記のコマンドは、 ( ) の名前を に 変更しようとします。root (つまり ) として実行している場合、これによりファイルがルート ディレクトリに移動され、大きな混乱が生じます。(教訓: 必要であることが確実でない限り、 の下でコマンドを実行しないでください。) root として実行していない場合、「良いニュース」は、コマンドが何も行わないことです。./fat cat.txtfat cat.txt./fat cat.txt/fatcattxtsudosudo

    それで、これらをまとめると、

    find . -type f -name "*[ ,.()]*" -exec bash -c 'for f do dir="$(dirname "$f")"; base="$(basename "$f")"; echo mv -n -- "$f" "$dir/${base//[ ,.()]}"; done' sh {} +
    

    echo上記には、「事前によく確認する」ためのコマンドが含まれていることに注意してください。上記のコマンドを実行すると、mv必要なコマンドがすべて表示されます。問題がなければ、「 」を削除してコマンドを再度実行してくださいecho


ちなみに、質問で示したコマンドは、 .名前にスペースが含まれるディレクトリ内にあります。

関連情報