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


11

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

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

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

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

からman renameです。


renameコマンドについて何も知らないので、試してみればあなたrename 'y/a-z/A-Z/' *が望むものを手に入れられると思います。テストする場所に注意してください。
ワーウィック

再帰的ではありません(最初のものがそうでなかったため...)が機能します。なぜ私がそのことを自分で考えなかったのか理解できません:)
jnhghy-Alexandru Jantea 2014

Gillesの回答の質を考えると、自分よりも彼の回答を受け入れるほうが良いと思います。それは私のものよりもはるかに完全であり、あなたのオプションを説明します(そしてそれがどのように機能するか)。ありがとう。
ワーウィック

回答:


8

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

y/A-Z/a-z/範囲内の各文字を変換しAZ範囲内の対応する文字にa通じz、対応する小文字の文字にすなわちASCII大文字。逆の変換を実行するには、を使用しますy/a-z/A-Z/。同じコマンドであるを書くための別の方法はrename '$_ = uc($_)' *ucであるuの PPER C ASE機能、および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 zmv1回実行してアクティブにします(この行をに入れます.zshrc)。

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

zmv -w '**/*' '$1$2:u'

説明:

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

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

zmv書き込んだコマンドがわからない場合は、-nオプションを渡して、コマンドの動作を印刷し、何も変更しないようにすることができます。出力を確認し、期待どおりに機能する場合は-n、実際に動作することなくコマンドを再実行します。


5

Gillesから盗まれた(マイナー編集あり)投稿はこちら

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


これは再帰的に機能しません。
Gilles「SO-邪悪なことをやめなさい」14/07/14

そうだね。質問をきちんと読んだほうがいい。名前変更コマンドにアクセスできませんが、これは再帰的に機能すると思いますfind <dir> -exec rename 'y/a-z/A-Z/' {} \;
Warwick

findが再帰しているときにディレクトリの名前を変更しているので、それよりも少し複雑です。
Gilles「SO-邪悪なことをやめなさい」14/07/14

@ギレス-はい。少し調べたところ、-depthオプションを追加して、ディレクトリ名が最後に処理されるように検索する必要があるようです。したがってfind <dir> -depth -exec rename 'y/a-z/A-Z/' {} \;、ディレクトリの名前変更の問題を処理する必要があります。正しい?
ワーウィック

いいえ、それはまだ機能しません。renameたとえば、その時点でfoo/barへの変更FOO/BARFOOその時点での変更がないためです。
Gilles「SO-邪悪なことをやめよ」14/07/14

2

この回答にまだリンクしているすべての人に Guiles Quernotがこの質問に求めた必要のない優れた回答を紹介したいと思いますfind

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

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

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

最後に誰かがy///コマンドが何をするのか疑問に思っている場合に備えてperl regex。ここに関連ドキュメントへのリンクがあります


1

find -execdir| リネーム

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

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

-execdir最初のcdベース名にのみ実行する前に、ディレクトリにね。

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


0

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

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

lsの出力を解析せず(そして、ls -lいったいなぜ名前以外の列を切り捨てるためだけに実行するのでしょうか?)、変数の置換を二重引用符で囲みます。コードが複雑すぎて、空白やその他の特殊文字を含むファイル名が壊れます。findまたは**/を使用してサブディレクトリに再帰しlsます。の出力は人間が使用するためのものです。
Gilles「SO-邪悪なことをやめなさい」14/07/14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.