Linuxですべてのフォルダーとファイルの名前を小文字に変更するにはどうすればよいですか?


179

大文字がどこにも表示されないように、完全なフォルダーツリーの名前を再帰的に変更する必要があります(C ++ソースコードですが、問題ではありません)。

CVSおよびSubversionバージョン管理ファイル/フォルダーを無視することのボーナスポイント。シェルはどのLinuxボックスでも使用できるはずなので、シェルスクリプトが推奨されます。

ファイル名の変更の詳細について、いくつかの有効な引数がありました。

  1. 同じ小文字の名前のファイルは上書きする必要があると思います。それはユーザーの問題です。大文字と小文字を区別しないファイルシステムでチェックアウトすると、最初のファイルシステムも後者で上書きされます。

  2. 私はAZ文字を検討し、それらをa〜zに変換します。他のすべては問題を引き起こしているだけです(少なくともソースコードに関して)。

  3. Linuxシステムでビルドを実行するにはスクリプトが必要になるため、CVSまたはSubversionバージョン管理ファイルへの変更は省略すべきだと思います。結局のところ、それは単なるスクラッチチェックアウトです。おそらく「エクスポート」がより適切です。


以前に投稿されたものはそのまま、または単純なケースではいくつかの調整を行うだけで完全に機能しますが、バッチの名前変更を実行する前に考慮する必要のある状況がいくつかあります。1.複数の名前が以下のような場合だけが異なるパス階層の同じレベルABCdefabcDEFおよびaBcDeF?名前変更スクリプトは中止する必要がありますか、それとも警告して続行しますか?2. US-ASCII以外の名前の小文字をどのように定義しますか?そのような名前が存在する可能性がある場合、最初にチェックと除外のパスを実行する必要がありますか?3.名前変更操作を実行している場合
Mihai Limbășan

回答:


179

"rename"次のコマンドを使用した簡潔なバージョン:

find my_root_dir -depth -exec rename 's/(.*)\/([^\/]*)/$1\/\L$2/' {} \;

ディレクトリとこのことを回避する問題は、ファイルの前に名前を変更し、(例えば、非既存のディレクトリにファイルを移動しようとしている"A/A""a/a")。

または、を使用しない、より詳細なバージョン"rename"

for SRC in `find my_root_dir -depth`
do
    DST=`dirname "${SRC}"`/`basename "${SRC}" | tr '[A-Z]' '[a-z]'`
    if [ "${SRC}" != "${DST}" ]
    then
        [ ! -e "${DST}" ] && mv -T "${SRC}" "${DST}" || echo "${SRC} was not renamed"
    fi
done

PS

後者の場合、移動コマンド(たとえば、"svn mv")を使用すると柔軟性が向上します。


36
名前変更の使用は、この方法で行うこともできますし、 'y / AZ / az /'の名前を変更することもできます*
Tzury Bar Yochay

3
注意してください、両方のバージョンは大文字と小文字を区別しないファイルシステムでは動作しません。私の場合、-でthen囲まれた行をに置き換えました(mv "${SRC}" "${DST}.renametmp" && mv "${DST}.renametmp" "${DST}") || echo "${SRC} was not renamed"
Lloeki、2011

6
2番目のアプローチは、空白スペース(コンテキスト:linux、bash)を含むファイルでは正しく機能しませんでした。
薄暗い

4
名前変更の最新バージョンを使用すると、正規表現は必要ありません。完全なコマンドはになりfind my_root_dir -depth -exec rename -c {} \;ます。大文字と小文字を区別しないファイルシステム(Macなど)を使用している場合は、-fを追加して名前を変更します
Javache

2番目のものは、Solarisでコマンド-Tからを削除することで機能しましたmv
ハム

261

もっと小さくても、私はかなり好きです:

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

OS XのHFS +などの大文字と小文字を区別しないファイルシステムでは、-fフラグを追加する必要があります。

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

3
linux.icydog.net/rename.phpThe renaming utility that comes by default with Ubuntu is a Perl program sometimes called prename
sleepsort

1
おかげで、私はこのように使用しました$ find | xargsが 'y / AZ / az /'の名前を変更*
Rashi

5
これは、perlsの名前変更があることを前提としていますが、常にそうとは限りません。たとえば、私のdebianの名前変更は完全に異なります
KrzysztofKrasoń15年

10
Archでは、プログラムが呼び出されますperl-rename(同じ名前のパッケージによって提供されます)
jaymmer-Reinstate Monica

3
「名前の変更」は再帰的ではないので、これは与えられた問題に答えません。
Cybolic 2016

89
for f in `find`; do mv -v "$f" "`echo $f | tr '[A-Z]' '[a-z]'`"; done

スクリプトを実行する前に、「mkdir -p A / B / C」を実行してください。
tzot 2008

2
「find」は、名前を変更したいファイルのリストを取得するために使用するコマンドで置き換える必要があります。たとえば、「ls *。{C、CPP、H}」です。
JPaget 14

2
OS Xでは機能せず、の使用情報を出力するだけですfindfind .これを修正するようです。
emlai

3
すべてのコメントからの「統合」バージョン(回答はもう編集できません):for f in `find .`; do mv -v "$f" "`echo $f | tr '[A-Z]' '[a-z]'`"; done
romaricdrigon '20 / 06/20

1
なぜこれが最初に機能するのか、誰かに説明してくれる?./FOOおよび./FOO/BARが見つかった場合、最初に./FOOの名前を./fooに変更します。その後、。/ FOO / BARは見つかりません。これを修正するには、以下に自分の答えを入力してください。
oisyn

80

効率を気にする必要がない場合は、以下を試してください。

zip -r foo.zip foo/*
unzip -LL foo.zip

13
うわー、それはかなり非効率的な方法です。
Artjom B. 14

28
ディレクトリ内のファイルの名前を変更する必要がある場合、計算効率は通常問題ではないと仮定すると...これはおそらく、このスレッドで最も創造的に単純なソリューションだと思います。実際、この簡単なことは、受け入れられた回答が示すほど複雑であってはならず、この回避策は、このような操作に投資したい考えの量にはるかに比例します。+1000
ピーターM.エリアス

27
-0(「ゼロ」、圧縮なし)スイッチでスピードを上げることができzip -0 -r foo.zip foo/ます。
ジョニーバロニー

3
異なるディレクトリ構造で50,000を超えるファイル名を変更する必要がありました。元の受け入れられた回答では、2分間で作業のわずか10%しか行われませんでした-0
ペオン2017

2
これは非効率的なだけではありません。一時アーカイブ用の十分な空き容量がない場合、これは単に不可能です。
Victor Yarema

19

男、あなた/ギャルは物事を複雑にするのが好きです...使用:

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

2
これは機能せず、小文字の名前のファイルがすでに存在していると表示されます。
kirhgoff 2017

@kirhgoff NFSマウントで発生することを確認しました- こちらの手順に従ってください。
joebeeson 2017年

大文字と小文字を区別するファイルシステムでどのように名前を変更できますか?rename 'y/a-z/A-Z/' /tmp/*.jpg-> Can't rename /tmp/*.jpg /TMP/*.JPG: No such file or directory、つまり、ファイルだけでなくパス全体の名前を変更してみます。
パブロA

14

上記の回答のほとんどは、奇数文字を含む名前を処理しないため危険です。この種のものに対する最も安全な賭けは、ファイル名を\ nではなくASCII NULで終了するfind-print0オプションを使用することです。

以下は、混乱しないようにファイルのみを変更し、ディレクトリ名は変更しないスクリプトですfind

find .  -type f -print0 | xargs -0n 1 bash -c \
's=$(dirname "$0")/$(basename "$0");
d=$(dirname "$0")/$(basename "$0"|tr "[A-Z]" "[a-z]"); mv -f "$s" "$d"'

私はそれをテストしましたが、スペースやあらゆる種類の引用符などを含むファイル名で動作します。ルートとして、他のスクリプトの1つを、

touch \;\ echo\ hacker::0:0:hacker:\$\'\057\'root:\$\'\057\'bin\$\'\057\'bash

...よくわかります...


rename代わりに使用する方が簡単ですmv
Victor Yarema

14

これは、(たとえばMacでのbrew installを使用して)名前変更コマンドをすでに持っているか、設定している場合に機能します。

rename --lower-case --force somedir/*

9
...名前を最初に設定した場合(例:brew install rename
pduersteler

3
'y / AZ / az /'の名前を変更*
Stephen

4
--lower-case?悲しいことに、少なくともArch Linuxではそうではありません。

3
renameはbashビルトインではありません。これは外部ユーティリティであり、インストールされているバージョンによって構文が異なります。この答えは、「すべてのUNIXベースのOS向け」のポータブルソリューションとしては十分とは言えません。
Corey Goldberg

2
チェックrenameしたところ、最新のFedora(28)に含まれているコマンドをutil-linux-2.31パッケージで使用する--lower-case場合、オプションはありません。
niXar 2018

11

これはCentOSで動作します/は、renamePerlスクリプトなし Red Hat Linuxまたは他のディストリビューションで動作します。

for i in $( ls | grep [A-Z] ); do mv -i "$i" "`echo $i | tr 'A-Z' 'a-z'`"; done

ソース:すべてのファイル名を大文字から小文字に変更します

(一部のディストリビューションでは、デフォルトのrenameコマンドはutil-linuxからのものであり、これは別の互換性のないツールです。)


これは再帰的にではなく単一のディレクトリでのみ機能します
Bram

クール..うまくいく
マニカンダンラム

6

Mac OS Xで見つけた最も簡単な方法は、http//plasmasturm.org/code/rename/の renameパッケージを使用することでした。

brew install rename
rename --force --lower-case --nows *

--force宛先名を持つファイルがすでに存在する場合でも名前を変更します。

--lower-caseファイル名をすべて小文字に変換します。

--nowsファイル名の空白のシーケンスをすべて単一のアンダースコア文字に置き換えます。


5

Bashシェルスクリプトを使用した、次善のソリューションを次に示します。

#!/bin/bash
# First, rename all folders
for f in `find . -depth ! -name CVS -type d`; do
   g=`dirname "$f"`/`basename "$f" | tr '[A-Z]' '[a-z]'`
   if [ "xxx$f" != "xxx$g" ]; then
      echo "Renaming folder $f"
      mv -f "$f" "$g"
   fi
done

# Now, rename all files
for f in `find . ! -type d`; do
   g=`dirname "$f"`/`basename "$f" | tr '[A-Z]' '[a-z]'`
   if [ "xxx$f" != "xxx$g" ]; then
      echo "Renaming file $f"
      mv -f "$f" "$g"
   fi
done

フォルダの名前はすべて正しく変更されており、 mv、アクセス許可が一致しない場合は質問されず、CVSフォルダーの名前も変更されません(そのフォルダー内のCVS制御ファイルの名前は、残念ながらまだ変更されています)。

「find -depth」と「find | sort -r」はどちらも名前変更に使用できる順序でフォルダーリストを返すため、フォルダーの検索には「-depth」を使用することをお勧めします。


最初の検索は機能しません。「mkdir -p A / B / C」を試してから、スクリプトを実行してください。
tzot 2008

4

元の質問では、SVNおよびCVSディレクトリを無視するように求められました。これは、findコマンドに-pruneを追加することで実行できます。たとえば、CVSを無視するには:

find . -name CVS -prune -o -exec mv '{}' `echo {} | tr '[A-Z]' '[a-z]'` \; -print

[編集]私はこれを試してみましたが、小文字の翻訳をfindの中に埋め込むことは、私が実際に理解していない理由で機能しませんでした。したがって、これを次のように修正します。

$> cat > tolower
#!/bin/bash
mv $1 `echo $1 | tr '[:upper:]' '[:lower:]'`
^D
$> chmod u+x tolower 
$> find . -name CVS -prune -o -exec tolower '{}'  \;

イアン


4

Larry Wallのファイル名フィクサーを使用する:

$op = shift or die $help;
chomp(@ARGV = <STDIN>) unless @ARGV;
for (@ARGV) {
    $was = $_;
    eval $op;
    die $@ if $@;
    rename($was,$_) unless $was eq $_;
}

それはと同じくらい簡単です

find | fix 'tr/A-Z/a-z/'

fixもちろん、上記のスクリプトはここにあります)


3

これはあなたが要求したことをする小さなシェルスクリプトです:

root_directory="${1?-please specify parent directory}"
do_it () {
    awk '{ lc= tolower($0); if (lc != $0) print "mv \""  $0 "\" \"" lc "\"" }' | sh
}
# first the folders
find "$root_directory" -depth -type d | do_it
find "$root_directory" ! -type d | do_it

最初の検索の-depthアクションに注意してください。


1
スレッド全体からMacで動作した唯一のもの。どうもありがとう!
YemSalat

2

移植性はなく、Zshのみですが、かなり簡潔です。

まず、zmvが読み込まれていることを確認します。

autoload -U zmv

また、extendedglobオンであることを確認してください:

setopt extendedglob

次に使用します:

zmv '(**/)(*)~CVS~**/CVS' '${1}${(L)2}'

名前がCVSではないファイルおよびディレクトリを再帰的に小文字にする。


2
for f in `find -depth`; do mv ${f} ${f,,} ; done

find -depth各ファイルとディレクトリを出力します。ディレクトリの内容は、ディレクトリ自体の前に出力されます。${f,,}ファイル名を小文字にします。


これは機能しません。コンテンツを操作する前にディレクトリの名前を変更するため、後でコンテンツを試すことができません。
プルーン

-depth修正を追加します!これは非常に迅速な解決策ですが、もちろん-print0、検索オプションを使用しないと、最も信頼性が高くなります
jpaugh

@jpaughいいえ、ありません。./FOO/BARの名前を./foo/barに変更しようとしますが、その時点ではまだ./fooは存在しません。
oisyn

2

MacOSでは、

renameパッケージをインストールし、

brew install rename

使用する、

find . -iname "*.py" -type f | xargs -I% rename -c -f  "%"                       

このコマンドは、*.py拡張子を持つすべてのファイルを検索し、ファイル名を小文字に変換します。

`f` - forces a rename

例えば、

$ find . -iname "*.py" -type f
./sample/Sample_File.py
./sample_file.py
$ find . -iname "*.py" -type f | xargs -I% rename -c -f  "%"
$ find . -iname "*.py" -type f
./sample/sample_file.py
./sample_file.py

なぜここで-Iオプションを使用しxargsたのですか?
Victor Yarema

- Iフラグは必須ではありません。で複数のコマンドを実行するときに使用されますxargs。ここで複数のコマンドを使用する例であるxargs cat foo.txt | xargs -I % sh -c 'echo %; mkdir %' なしに実行することができます-Iようにfind . -iname "*.py" -type f | xargs -I% rename -c -f "%"
akileshラジは

2

タイプセットを使用:

typeset -l new        # Always lowercase
find $topPoint |      # Not using xargs to make this more readable
  while read old
  do new="$old"       # $new is a lowercase version of $old
     mv "$old" "$new" # Quotes for those annoying embedded spaces
  done

Windowsでは、Git Bashなどのエミュレーションは、Windowsの内部では大文字と小文字が区別されないため、失敗する可能性があります。それらについては、mv最初に「$ old.tmp」のような別の名前のファイルであるステップを追加し、次にに追加し$newます。


1

時間がかかるが「驚きもインストールもない」

このスクリプトは、スペース、引用符、その他の異常な文字およびUnicode を含むファイル名を処理し、大文字と小文字を区別しないファイルシステムと、 bashおよびawkがインストールされているほとんどのUnix-y環境(つまり、ほとんどすべて)で機能します。また、衝突があれば(ファイル名を大文字のままにして)報告し、ファイルとディレクトリの両方の名前を変更して再帰的に動作します。最後に、それは高度に適応可能です。必要なファイル/ディレクトリをターゲットにするためにfindコマンドを微調整でき、awkを微調整して他の名前操作を実行できます。「Unicodeを処理する」とは、実際に大文字と小文字を変換することを意味することに注意してください(を使用する回答のように無視しないでくださいtr)。

# adapt the following command _IF_ you want to deal with specific files/dirs
find . -depth -mindepth 1 -exec bash -c '
  for file do
    # adapt the awk command if you wish to rename to something other than lowercase
    newname=$(dirname "$file")/$(basename "$file" | awk "{print tolower(\$0)}")
    if [ "$file" != "$newname" ] ; then
        # the extra step with the temp filename is for case-insensitive filesystems
        if [ ! -e "$newname" ] && [ ! -e "$newname.lcrnm.tmp" ] ; then
           mv -T "$file" "$newname.lcrnm.tmp" && mv -T "$newname.lcrnm.tmp" "$newname" 
        else
           echo "ERROR: Name already exists: $newname"
        fi
    fi    
  done
' sh {} +

参考文献

私のスクリプトはこれらの優れた答えに基づいています:

/unix/9496/looping-through-files-with-spaces-in-the-names

Bashで文字列を小文字に変換する方法は?


1

これはmacOSでもうまく動作します:

ruby -e "Dir['*'].each { |p| File.rename(p, p.downcase) }"

RubyはmacOSに同梱されているため、これは特に便利です。
jxmorris12

1

私はWindows 7のCygwinセットアップでこれを行う必要があり、上記の提案を試したところ構文エラーが発生することがわかりました(ただし、有効なオプションを見逃している可能性があります)。ただし、Ubuntuフォーラムからのこのソリューションは、缶詰からうまくいきました:-)

ls | while read upName; do loName=`echo "${upName}" | tr '[:upper:]' '[:lower:]'`; mv "$upName" "$loName"; done

(注:以前に空白をアンダースコアに置き換えていました:

for f in *\ *; do mv "$f" "${f// /_}"; done


1

OS Xではmv -f「同じファイル」エラーが表示されるため、2回名前を変更します。

for i in `find . -name "*" -type f |grep -e "[A-Z]"`; do j=`echo $i | tr '[A-Z]' '[a-z]' | sed s/\-1$//`; mv $i $i-1; mv $i-1 $j; done

1

この状況では、スペースやスラッシュのないパスを楽観的に仮定することを避けるために、Pythonに手を伸ばします。またpython2、より多くの場所にインストールされる傾向があることもわかりましたrename

#!/usr/bin/env python2
import sys, os

def rename_dir(directory):
  print('DEBUG: rename('+directory+')')

  # Rename current directory if needed
  os.rename(directory, directory.lower())
  directory = directory.lower()

  # Rename children
  for fn in os.listdir(directory):
    path = os.path.join(directory, fn)
    os.rename(path, path.lower())
    path = path.lower()

    # Rename children within, if this child is a directory
    if os.path.isdir(path):
        rename_dir(path)

# Run program, using the first argument passed to this Python script as the name of the folder
rename_dir(sys.argv[1])

複雑にすることについて話してください... .. 'y / AZ / az /'の名前を変更してください*
Stephen

1
@Stephen、名前変更をインストールするための管理者アクセス権があることを前提としています。他のソフトウェアをインストールすることができないシステムでは、データを頻繁に変更する必要があります。最近のUbuntuでは、これはperlが存在する場合にのみインストールされます。
John Foley

1

Arch Linuxを使用している場合は、コマンドを実行可能ファイルとして提供するrename)パッケージと、AURそれに付随するマニュアルページをインストールできます。renamexm/usr/bin/renamexm

これは、ファイルとディレクトリの名前をすばやく変更するための非常に強力なツールです。

小文字に変換

rename -l Developers.mp3 # or --lowcase

大文字に変換

rename -u developers.mp3 # or --upcase, long option

別のオプション

-R --recursive # directory and its children

-t --test # Dry run, output but don't rename

-o --owner # Change file owner as well to user specified

-v --verbose # Output what file is renamed and its new name

-s/str/str2 # Substitute string on pattern

--yes # Confirm all actions

必要に応じて、ここからサンプルのDevelopers.mp3ファイルをフェッチできます;)


1
brewmacOSでの名前の変更は-l、シンボリックリンクの作成-cと小文字への変換にバインドされているため、注意してください。
rien333 2017

0
( find YOURDIR -type d | sort -r;
  find yourdir -type f ) |
grep -v /CVS | grep -v /SVN |
while read f; do mv -v $f `echo $f | tr '[A-Z]' '[a-z]'`; done

最初にディレクトリの名前を下から上に並べ替え-r(-depthは使用できません)、次にファイルの名前を変更します。次に、find ...- pruneの代わりにgrep -v / CVSを使用します。大きなディレクトリの場合、f in ...は一部のシェルバッファをオーバーフローする可能性があります。検索を使用... | 読みながらを避けるためにいる間。

そして、はい、これはケースのみが異なるファイルを破壊します...


まず、find YOURDIR -type d | sort -r面倒です。あなたが欲しいfind YOURDIR -depth -type d。次に、find -type fディレクトリの名前が変更された後に実行する必要があります。
tzot 2008

0
find . -depth -name '*[A-Z]*'|sed -n 's/\(.*\/\)\(.*\)/mv -n -v -T \1\2 \1\L\2/p'|sh

ここで説明したより複雑なスクリプトは試していませんが、Synology NASで機能する単一のコマンドラインバージョンはありません。renameは利用できず、バリエーションの多くはfindすでに名前が変更されたパスの古い名前に固執するため失敗失敗します(たとえば、パスの./FOO後にが見つかった場合./FOO/BAR、に名前./FOOを変更して./fooも引き続きリストされます)./FOO/BARても、そのパスが無効になってもます) 。上記のコマンドは問題なく動作しました。

次に、コマンドの各部分について説明します。


find . -depth -name '*[A-Z]*'

これは.、深さ優先検索(たとえば、の./foo/bar前にリストされます)を使用して、現在のディレクトリからファイルを検索し(処理するディレクトリに変更します)、./foo大文字を含むファイルのみを検索します。-nameフィルタは、ベースファイル名ではなくフルパスに適用されます。したがって、これはリストされます./FOO/BARが、されません./FOO/bar。名前を変更したくないので、これで問題ありません./FOO/bar./FOOただし、名前を変更したいのですが、後でリストします(これ-depthが重要な理由です)。

このコマンド自体は、最初に名前を変更するファイルを見つけるのに特に役立ちます。完全な名前変更コマンドの後にこれを使用して、ファイル名の競合またはエラーのためにまだ置換されていないファイルを検索します。


sed -n 's/\(.*\/\)\(.*\)/mv -n -v -T \1\2 \1\L\2/p'

この部分は、によって出力されたファイルを読み取り、findそれらをmv正規表現を使用コマンドで。-nオプションは停止しsed、入力を印刷するから、そしてp検索と置換正規表現の出力置き換えるテキスト内のコマンド。

正規表現自体は2つのキャプチャで構成されています。最後の/(ファイルのディレクトリ)までの部分と、ファイル名自体です。ディレクトリはそのまま残りますが、ファイル名は小文字に変換されます。したがって、find出力すると./FOO/BAR、になりmv -n -v -T ./FOO/BAR ./FOO/barます。の-nオプションはmv、既存の小文字のファイルが上書きされないようにします。この-vオプションは、実行するmvすべての変更を出力します(または、実行しない場合- ./FOO/barすでに存在する場合は、./FOO/BAR -> ./FOO/BAR変更が加えられていないことに注意して、などの出力を行います)。ここ-Tで非常に重要です-ターゲットファイルをディレクトリとして扱います。これ./FOO/BARにより./FOO/bar、そのディレクトリがたまたま存在する場合に移動されないようになります。

これを一緒に使用して、find実行されるコマンドのリストを生成します(実際に実行せずに何が行われるかを確認するのに便利です)


sh

これはかなり自明です。生成されたすべてのmvコマンドをシェルインタープリターにルーティングします。あなたはそれをbash好きなシェルに置き換えることができます。


0

Slugify Rename(正規表現)

それは正確にはOPが要求したものではなく、このページで見つけたいと思っていたものです。

ファイルの名前を変更してURLに似た "slugify"バージョン(つまり、英数字、ドット、ダッシュのみを含める):

rename "s/[^a-zA-Z0-9\.]+/-/g" filename

2
"ではない正確に"?これは、OPが要求したものとはまったく
Corey Goldberg
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.