web-dev-qa-db-ja.com

複数のファイル名の一部を小文字にしようとすると、名前の変更で「bareword not allowed」が返される

Ubuntu 16.04のフォルダーに2つのファイルがあります。

a1.dat
b1.DAT

b1.DATの名前をb1.datに変更したいので、結果としてフォルダーに次のファイルがあります。

a1.dat
b1.dat

試しました(失敗しました):

$ rename *.DAT *.dat
Bareword "b1" not allowed while "strict subs" in use at (user-supplied code).
Bareword "DAT" not allowed while "strict subs" in use at (user-supplied code).

そして

$ find . -iname "*.DAT" -exec rename DAT dat '{}' \;
Bareword "DAT" not allowed while "strict subs" in use at (user-supplied code).
Bareword "DAT" not allowed while "strict subs" in use at (user-supplied code).

これを検索しても意味のある解決策はありませんでした...

10
Samo

このエラーは、Perl renameに由来するようです。引用符を使用する必要がありますが、変更する部分、検索および置換スタイルを指定するだけです。構文は次のとおりです。

rename -n 's/\.DAT/\.dat/' *

テスト後に-nを削除して、実際にファイルの名前を変更します。

隠しファイルを含めるには、コマンドを実行する前にglob設定を変更します。

shopt -s dotglob

ファイルの名前を再帰的に変更する場合は、次を使用できます。

shopt -s globstar
rename -n 's/\.DAT/\.dat/' **

または、現在のディレクトリ内またはその下に、.DATで終わらない多くのパスがある場合、2番目のコマンドでそれらのパスを指定する方が良いでしょう:

rename -n 's/\.DAT/\.dat/' **/*.DAT

ファイルが.DATで終わらないさまざまな名前を持つ場合、これは高速になります。[1]

これらの設定をオフにするには、shopt -u、たとえばshopt -u globstarを使用できますが、デフォルトではオフになっており、新しいシェルを開くとオフになります。

この結果、引数リストが過度に長くなる場合、たとえば、findを使用できます。

find -type f -name "*.DAT" -exec rename -n -- 's/\.DAT/\.dat/' {} \;

またはそれ以上

find -type f -name "*.DAT" -exec rename -n -- 's/\.DAT/\.dat/' {} +

find ... -exec+とともに使用すると、見つかったファイルから引数リストを作成するため、\;を使用するよりも高速です。元々、私はあなたがそれを使用することは不可能だと思っていました、あなたはあなたがargument list too long問題を抱えていると述べたので、今私はそれを避けるために必要に応じてコマンドの複数の呼び出しに巧妙に分割されることを知っています問題[2]

renameはすべてのファイル名を同じ方法で処理するため、複数の呼び出しに安全に分割できるため、引数リストの長さは関係ありません。 -execで使用しているコマンドが複数の引数を受け入れない場合、または引数を特定の順序にする必要がある場合、またはその他の理由で引数リストを分割すると望ましくないことが発生する場合は、\;を使用してコマンドを実行できます見つかったファイルごとに1回呼び出されます(引数リストが他のメソッドに対して長すぎる場合、これには時間がかかります!)。


Eliah Kagan に感謝します。この回答を改善するための非常に有用な提案に対して:

[1] グロビング時のファイル名の指定
[2] find ... -exec with +は引数リストを分割します

11
Zanna

できるよ:

rename -n 's/DAT$/\L$&/' *.DAT

実際の名前変更を行うには、-nをドロップします。

  • globパターン*.DATは、現在のディレクトリの.DATで終わるすべてのファイルに一致します

  • renameの置換では、DAT$は末尾のDATと一致します

  • \L$&は一致全体を小文字にします。 $&は一致全体を指します

b1.DATだけをしたい場合:

rename -n 's/DAT$/\L$&/' b1.DAT

例:

% rename -n 's/DAT$/\L$&/' *.DAT
rename(b1.DAT, b1.dat)
6
heemayl