web-dev-qa-db-ja.com

名前変更を使用してすべてを大文字に再帰的に名前変更するにはどうすればよいですか

すべてのファイルとフォルダ(サブフォルダ)を大文字に再帰的に名前変更したいのですが。

小文字に変換するスクリプトをいくつか見つけましたが、それらを逆に(小文字から大文字に)変換するように変更する方法がわかりません。

私が見つけて小文字で動作するスクリプトですが、変更する方法がわかりませんでした。

rename 'y/A-Z/a-z/' *

man renameからです。

Debianとその派生物(Ubuntu、Mintなど)によって配布された Perlスクリプトrename を使用していることに注意してください。他のLinuxディストリビューションは rename と呼ばれる完全に異なる、あまり有用ではないコマンドを出荷しています。

_y/A-Z/a-z/_は、AからZの範囲の各文字をaからzの範囲の対応する文字に変換します。つまり、ASCII大文字から対応する小文字へ。逆の変換を実行するには、_y/a-z/A-Z/_を使用します。同じコマンドを書くもう1つの方法はrename '$_ = uc($_)' *です-— ucuppercase関数、およびrenameコマンドは、_$__変数に対して行われた変換に基づいてファイルの名前を変更します。

_rename '…' *_は、_*_と一致するため、現在のディレクトリ内のファイルの名前のみを変更します。 ドットファイル (名前が_._で始まるファイル)もスキップされます。

現在のディレクトリおよびサブディレクトリにあるファイルの名前を再帰的に変更する場合は、 find コマンドを使用して、現在のディレクトリを再帰的にたどることができます。ここに問題があります。renameを呼び出すと、ディレクトリとベース名部分の両方の名前が変更されます。再帰する前にディレクトリでrenameを呼び出すと(_find -exec rename … {} \;_)、findはディレクトリを見つけたが、下降しようとするときまでにそのディレクトリが存在しないため、混乱します。その中に。これに対処するには、findに、それを処理する前にディレクトリをトラバースするように指示しますが、結局、_foo/bar_を_FOO/BAR_に名前変更しようとしますが、ディレクトリFOO存在しません。

この問題を回避する簡単な方法は、名前変更コマンドをパスのベース名部分のみに作用させることです。正規表現_([^/]*\Z)_は、_/_を含まないパスの最後の部分に一致します。

_find . -depth -exec rename 's!([^/]*\Z)!uc($1)!e' {} +
_

シェル zsh は、名前を変更するためのより便利な機能を提供します。Perlよりもさらに不可解ですが、簡潔で、多くの場合、構成が簡単です。

関数 zmv は、パターンに基づいてファイルの名前を変更します。 _autoload -U zmv_を1回実行してアクティブにします(この行を_.zshrc_に入れます)。

zmv(置き換えるパターン)の最初の引数では、zshの強力な ワイルドカードパターン を使用できます。 zmvの2番目の引数(置換テキスト)では、その パラメータ展開 機能を使用できます。これには 履歴修飾子 が含まれます。

_zmv -w '**/*' '$1$2:u'
_

説明:

  • _-w_ —各ワイルドカードパターンに数値変数を自動的に割り当てます
  • _**/*_ —サブディレクトリ内のすべてのファイルを再帰的に(_**/_は0、1以上のレベルのサブディレクトリに一致)
  • _$1_ —最初の数値変数。ここでは、各パスのディレクトリ部分と一致しています。
  • _$2:u_ — 2番目の数値変数。ここでは、各パスのベース名部分に一致し、値を大文字に変換する_:u_修飾子を使用しています。

追加のボーナスとして、これはアンビエントロケール設定を尊重します。

作成したzmvコマンドがわからない場合は、_-n_オプションを渡して、コマンドの実行内容を出力し、何も変更しないようにすることができます。出力を確認し、期待どおりに機能する場合は、_-n_を使用せずにコマンドを再実行して実際に動作させます。

Gillesの投稿から盗まれた(マイナーな編集あり) here

find <DIR> -depth -type d -exec rename -n 's!/([^/]*/?)$!\U/$1!' {} +

5
Warwick

この回答にまだリンクしている人は誰にでも 優れた回答 ギレス・ケルノットがfindを必要としないこの質問に向けたものを紹介したいと思います。

結果のコマンドは次のようになります。

shopt -s globstar
rename -n 'y/a-z/A-Z/' **

ただし、実行する前に、古いbashバージョンに関する警告についてリンクされている回答を読んでください。

最後に誰かがy///コマンドはPerl regex関連ドキュメント へのリンクは次のとおりです。

2
Marcelo Lacerda

find -execdir |名前変更

これは、Perlの正規表現fuがベース名にのみ作用することを回避するため、相対パスの狂気がなければ、これを行うのに最適な方法です。

PATH="$(echo "$PATH" | sed -E 's/(^|:)[^\/][^:]*//g')" \
  find a -depth -execdir rename 's/(.*)/\U$1/' '{}' \;

-execdir最初にcdsを実行してから、ベース名でのみ実行します。

残念ながら、そのPATHハッキング部分を取り除くことはできません。PATH...に相対パスがある場合、find -execdirは何もしません。: https ://askubuntu.com/questions/621132/why-using-the-execdir-action-is-insecure-for-directory-which-is-in-the-path/1109378#1109378

ファイルの名前を変更したいディレクトリに移動した後、これを試してください:

for Word in `ls -ltr |tail -n +2 |awk '{print $9}'`
do
  a=$(echo $Word | tr '[a-z]' '[A-Z]')
  mv $Word $a
  echo "Done Successfully"
done
0
Sorav