スクリプトは、ディレクトリ/サブディレクトリ内の各ファイルを繰り返し見て(シンボリックリンクをスキップ)、ファイル名を次のように置き換える必要があります。
- 複数の連続したスペースは1つのスペースのみです
- 複数の連続_1つだけを含む_
- 1つ以上の下線と1つ以上のスペース(下線は1つのみを含む)
- 下線の後 - 下線のみ
- - 後ろに下線が続き、下線のみが表示されます。
- 複数の連続した「.」には1点しかありません。
- ファイルサフィックスをすべて小文字にします(例:.PdFから.pdfへ)、これは単なる例です。
- @、$、または!などの文字を削除してください。
答え1
使用find
とPerl rename
:
注:Perlは、さまざまなLinuxディストリビューションでは、、、または.perlrename
としても知られています。機能とコマンドラインオプションが完全に異なり、互換性のないユーティリティと混同しないでください。file-rename
perl-rename
prename
rename
util-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