現在のディレクトリとサブディレクトリにある複数のファイルの名前を変更するスクリプト

現在のディレクトリとサブディレクトリにある複数のファイルの名前を変更するスクリプト

スクリプトは、ディレクトリ/サブディレクトリ内の各ファイルを繰り返し見て(シンボリックリンクをスキップ)、ファイル名を次のように置き換える必要があります。

  • 複数の連続したスペースは1つのスペースのみです
  • 複数の連続_1つだけを含む_
  • 1つ以上の下線と1つ以上のスペース(下線は1つのみを含む)
  • 下線の後 - 下線のみ
  • - 後ろに下線が続き、下線のみが表示されます。
  • 複数の連続した「.」には1点しかありません。
  • ファイルサフィックスをすべて小文字にします(例:.PdFから.pdfへ)、これは単なる例です。
  • @、$、または!などの文字を削除してください。

答え1

使用findとPerl rename

注:Perlは、さまざまなLinuxディストリビューションでは、、、または.perlrenameとしても知られています。機能とコマンドラインオプションが完全に異なり、互換性のないユーティリティと混同しないでください。file-renameperl-renameprenamerenameutil-linux

find . -type f -print0 |
  rename -n -0 '
    s/[\@\$!]//g;            # remove all @, $, and ! characters.

    # remove leading and trailing whitespace (if any) from filenames
    s/^\s+|\s*\z//sg;

    # change all runs of any whitespace to just one space
    s/\s+/ /sg;

    s/[- ]*([._])[- ]*/$1/g; # remove space(s) and - around _ and .

    s/\.\.+/./g;             # reduce multiple periods to just one
    s/__+/_/g;               # reduce multiple _ to just one
    s/_*\._*/./g;            # change _. and ._ to just .

    s=(\.[^./]*\z)=lc($1)=e; # lowercase filename suffixes
'

3番目の代替タイプは、1つ以上の連続した空白文字(実際の空白文字、タブ、改行、フォームフィードなどを含む)を単一の空白文字に置き換えます。 IMOは要求されたもの以上ですが、ファイル名の空白文字のみを変更するよりも、さまざまな種類の空白文字をすべて変更する方が便利です。必要なものがない場合(スペース2つとスペース1つ)\s+に変更してください++

4番目の置換()s/[- ]*([_.])[- ]*/$1/g;は、または前にスペースやダッシュ_が必要ないと仮定します.。これはあなたが要求したものよりも多いですが、実際に必要なものより多い場合は簡単に変更できます。

関連して、2番目の置換はとでのみ_.置き換えられます。これを行うと、同じファイル名を取得できません。このようなファイル名が必要な場合は、この行を削除してください。._.foo_.bar_._pdf

最後の置換の正規表現修飾子eは、置換がPerlコード(この場合はlc()入力を小文字にする関数)として評価されるようにします。

注:-nオプションの名前を変更して、実行するアクションのみを示すテスト実行にします。実際にファイル名を変更するには、ファイルを削除または-n変更して-v詳細な出力を取得します。

必要に応じて、複数行の名前変更スクリプトを1つの長く読み取れない行に圧縮することもできます(コメントを削除した場合)。#ただし、追加の改行とインデントを使用すると、コマンドラインで読みやすく編集が簡単になります。そしてスクリプトから。

最後に、これはあなたが言うとき「ディレクトリ/サブディレクトリ内のすべてのファイルを参照する(シンボルリンクをスキップ)」また、名前の変更からディレクトリ、デバイスノード、名前付きパイプ、ソケットなどを除外したいと思います。つまり、通常のファイルだけが名前が変更されます。

一致するディレクトリの名前を変更するには、に-type f変更findする必要があります\( -type f -o -type d \)

もちろん、希望の find 述語を使用して検索を絞り込むこともできます。

答え2

というユーティリティがあります。デトックスこれは多くの問題を解決することができます。 Webページから:

  • 大文字のASCII Latin-1(ISO 8859-1)文字(つまり、左右の二重引用符)を削除または置き換えます。可能であれば、代替文字が使用されます(たとえば、上記のアクセント付きの「A」が「A」に置き換えられます)。
  • UTF-8でエンコードされたUnicode文字を削除または置き換えます。これは、Unicodeの範囲がはるかに広いことを除いて、ISO 8859-1翻訳と同じように機能します。
  • スペースや(、)、@などのトリッキーなその他の文字を削除または置き換えます。ファイル名の先頭の「-」を削除します。
  • CGIエスケープされたASCII文字を削除または置き換えます。つまり、%20は ""(そして "_")になります。
  • 超過した「_」と「-」を切り捨てます。
  • ディレクトリ再帰、テスト実行、詳細リスト。
  • 安全を念頭に置いて設計されています。すでに存在するファイルは上書きされず、特殊ファイルは通常は触れません(ただし要求できます)。

答え3

そしてzsh

autoload -Uz zmv
zmv -n '(**/)(*)' '$1${${${${${2//[@\$!]}//[ _]##/_}//.##/.}//[-_]#_[-_]#/_}/%(#m).[^.]#/$MATCH:l}'

(満足のいく場合は-nテスト実行のために削除してください)。

これは一部の${param//pattern/replacemenet}演算子とネストされます。

  • ${2//[@\$!]}:(ファイルのデフォルト名)@ $ !からすべてのsを削除します。$2スペースが発生する可能性があるため、最初にこれを行うか、_後続-のステップで一緒に圧縮する必要があるかもしれません。
  • ${...//[ _]##/_}:上記の結果で、##1つ以上のスペース()またはアンダースコアを次に置き換えます。_
  • ${...//.##/.}:上記の結果の##1つ以上の()シーケンスを.次のように置き換えます。.
  • ${...//[-_]#_[-_]#/_}:上記結果に基づいて、0個以上(#_または-両面のある項目を削除します。__
  • ${.../%(#m).[^.]#/$MATCH:l}:修飾子を使用して、小文字に変換されたのと同じ内容で、末尾のa().と一連のs以外の文字を置き換えます(代替として一致を使用できるようにします)。.%(#m)$MATCH:l

zmvディレクトリの深さが最初に処理され(対応するポイントより前に)、名前の変更を開始する前にデータが失われていないことを確認するために、いくつかの完全性チェックによって交換が実行されます。

たとえば、次のようにします。

mv -- 'A _  - _  .. - b -c-d ..PDF' A_._b_c-d_.pdf

関連情報