完全なフォルダーツリーの名前を再帰的に変更して、大文字がどこにも表示されないようにする必要があります(C++ソースコードですが、それは問題ではありません)。 CVSおよびSVN制御ファイル/フォルダーを無視するためのボーナスポイント。シェルはどのLinuxボックスでも使用できるため、好ましい方法はシェルスクリプトです。
ファイルの名前変更の詳細については、いくつかの有効な引数がありました。
同じ小文字の名前のファイルは上書きされるべきだと思う、それはユーザーの問題だ。大文字と小文字を区別しないファイルシステムでチェックアウトすると、最初のファイルシステムも後者で上書きされます。
私はA-Z文字を検討し、それらをa-zに変換します、他のすべては問題を引き起こしています(少なくともソースコードで)。
Linuxシステムでビルドを実行するにはスクリプトが必要なので、CVSまたはSVN制御ファイルへの変更は省略すべきだと思います。結局のところ、それは単なるスクラッチチェックアウトです。たぶん「輸出」がより適切です。
"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
P. S.
後者の場合、移動コマンドでより柔軟になります(例:"svn mv"
)。
まだ小さい
rename 'y/A-Z/a-z/' *
OS XのHFS +などの大文字と小文字を区別しないファイルシステムでは、-fフラグを追加する必要があります。
rename -f 'y/A-Z/a-z/' *
for f in `find`; do mv -v "$f" "`echo $f | tr '[A-Z]' '[a-z]'`"; done
効率を気にする必要がない場合は、単にフォローしてみてください。
Zip -r foo.Zip foo/*
unzip -LL foo.Zip
上記の回答のほとんどは、奇妙な文字を含む名前を扱っていないため危険です。この種のことに対する最も安全な方法は、findの-print0オプションを使用することです。このオプションは、\ nの代わりにASCII NULでファイル名を終了します。ここで、このスクリプトを送信します。このスクリプトは、ディレクトリ名ではなくファイルのみを変更し、検索を混乱させないようにします。
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"'
私はそれをテストし、スペース、あらゆる種類の引用符などを含むファイル名で動作します。これは重要です。
touch \;\ echo\ hacker::0:0:hacker:\$\'\057\'root:\$\'\057\'bin\$\'\057\'bash
...よく推測してください...
君たちは、物事を複雑にしたい。
「y/A-Z/a-z /」の名前を変更*
renameコマンドを既に持っているかセットアップしている場合に機能します(例:Macでbrew installを使用):
rename --lower-case --force somedir/*
これは、CentOS/Redhatまたはrename
Perlスクリプトなしの他のディストリビューションで機能します。
for i in $( ls | grep [A-Z] ); do mv -i "$i" "`echo $i | tr 'A-Z' 'a-z'`"; done
ソース: https://linuxconfig.org/rename-all-files-from-uppercase-to-lowercase-characters
(一部のディストリビューションでは、デフォルトのrename
コマンドはutil-linuxからのもので、これは別の互換性のないツールです)
元の質問では、SVNおよびCVSディレクトリを無視するよう求められました。これは、findコマンドに-Pruneを追加することで実行できます。たとえば、CVSを無視するには:
find . -name CVS -Prune -o -exec mv '{}' `echo {} | tr '[A-Z]' '[a-z]'` \; -print
[編集]これを試してみましたが、小文字の翻訳を検索結果に埋め込むことは、実際にはわからない理由で機能しませんでした。したがって、これを次のように修正します。
$> cat > tolower
#!/bin/bash
mv $1 `echo $1 | tr '[:upper:]' '[:lower:]'`
^D
$> chmod u+x tolower
$> find . -name CVS -Prune -o -exec tolower '{}' \;
イアン
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」を使用することを好みました。
ラリーウォールのファイル名フィクサーの使用
$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/'
(修正はもちろん上記のスクリプトです)
これは、要求したことを実行する小さなシェルスクリプトです。
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アクションに注意してください。
以前に投稿されたものは、そのままでも完璧に機能しますが、簡単な場合にはいくつかの調整が必要ですが、バッチ名前変更を実行する前に考慮したい状況がいくつかあります。
ABCdef
、abcDEF
、aBcDeF
など、大文字と小文字のみが異なるパス階層の同じレベルに2つ以上の名前がある場合はどうなりますか?名前変更スクリプトを中止するか、警告して続行する必要がありますか?
US-ASCII以外の名前に小文字をどのように定義しますか?そのような名前が存在する可能性がある場合、最初にチェックと除外パスを実行する必要がありますか?
CVSまたはSVN作業コピーで名前変更操作を実行している場合、ファイル名またはディレクトリ名の大文字と小文字を変更すると、作業コピーが破損する可能性があります。スクリプトは、.svn/entriesやCVS/Entriesなどの内部管理ファイルも見つけて調整する必要がありますか?
for f in `find -depth`; do mv ${f} ${f,,} ; done
find -depth
は、各ファイルとディレクトリを印刷し、ディレクトリ自体の前にディレクトリの内容を印刷します。 ${f,,}
はファイル名を小文字にします。
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
この状況で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])
OSXでは、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
私はWindows 7のcygwinセットアップでこれを行う必要があり、上からの提案で構文エラーが発生したことがわかりました(ただし、作業オプションを見逃したかもしれませんが)から直接このソリューションは ubutuフォーラム はできませんでした:-)
ls | while read upName; do loName=`echo "${upName}" | tr '[:upper:]' '[:lower:]'`; mv "$upName" "$loName"; done
(nb私は以前に空白をアンダースコアに置き換えていました
for f in *\ *; do mv "$f" "${f// /_}"; done
MacOSXで見つけた最も簡単なアプローチは、 http://plasmasturm.org/code/rename/ から名前変更パッケージを使用することでした。
brew install rename
rename --force --lower-case --nows *
--force宛先名を持つファイルがすでに存在する場合でも名前を変更します。
--lower-caseファイル名をすべて小文字に変換します。
--nowsファイル名内の空白のすべてのシーケンスを単一のアンダースコア文字に置き換えます。
長いが、「驚きとインストールなしで動作する」
このスクリプトは、スペース、引用符、その他の珍しい文字およびUnicodeを含むファイル名を処理し、大文字と小文字を区別しないファイルシステムおよびほとんどのUnix-y環境で動作しますbashとawkがインストールされている(つまり、ほぼすべて)。また、もしあれば衝突を報告し(ファイル名を大文字のままにして)、もちろんファイルとディレクトリの両方の名前を変更し、再帰的に動作します。最後に、非常に順応性があります。findコマンドを微調整して目的のファイル/ディレクトリをターゲットにしたり、awkを微調整して他の名前操作を行うことができます。 「ユニコードを処理する」とは、実際に大文字と小文字を変換することを意味することに注意してください(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 {} +
参考文献
私のスクリプトは、これらの優れた答えに基づいています。
https://unix.stackexchange.com/questions/9496/looping-through-files-with-spaces-in-the-names
移植性はなく、Zshのみですが、かなり簡潔です。
まず、zmv
がロードされていることを確認してください。
autoload -U zmv
また、extendedglob
がオンになっていることを確認してください。
setopt extendedglob
次に使用します:
zmv '(**/)(*)~CVS~**/CVS' '${1}${(L)2}'
名前がCVSではないファイルおよびディレクトリを再帰的に小文字にします。
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
が入力を印刷するのを停止し、search-and-replace正規表現のp
コマンドは置換されたテキストを出力します。
正規表現自体は、最後の/(ファイルのディレクトリ)までの部分と、ファイル名自体の2つのキャプチャで構成されます。ディレクトリはそのまま残りますが、ファイル名は小文字に変換されます。したがって、find
が./FOO/BAR
を出力すると、mv -n -v -T ./FOO/BAR ./FOO/bar
になります。 mv
の-n
オプションは、既存の小文字ファイルが上書きされないようにします。 -v
オプションは、変更を行うたびにmv
を出力します(または、しない場合-./FOO/bar
が既に存在する場合、./FOO/BAR -> ./FOO/BAR
のようなものを出力します。作られた)。ここで-T
は非常に重要です-ターゲットファイルをディレクトリとして扱います。これにより、そのディレクトリが存在する場合に./FOO/BAR
が./FOO/bar
に移動しないようにします。
これをfind
と一緒に使用して、実行されるコマンドのリストを生成します(実際に実行せずに実行されることを確認するのに便利です)
sh
これは一目瞭然です。生成されたすべてのmv
コマンドをシェルインタープリターにルーティングします。 bash
またはお好みのシェルに置き換えることができます。
( 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
最初にディレクトリの名前を下から上に変更しますsort -r(-depthは使用不可)、次にファイル。次に、find ...- Pruneの代わりにgrep -v/CVSを使用します。大きなディレクトリの場合、for f in ...は一部のシェルバッファーをオーバーフローさせる可能性があります。それを避けるためにfind ... | while readを使用してください。
そして、はい、これは大文字と小文字のみが異なるファイルを上書きします...
Arch Linux を使用する場合、 rename
パッケージを AUR
からインストールできます。これはrenamexm
コマンドを/usr/bin/renamexm
実行可能ファイルおよびその- manual それとともにページ。
ファイルやディレクトリの名前をすばやく変更するための非常に強力なツールです。
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 # substite string on pattern
--yes # Confirm all actions
サンプルを取得できますDevelopers.mp3ファイル here 、必要に応じて;)
これはmacOSでもうまく機能します:
Ruby -e "Dir['*'].each { |p| File.rename(p, p.downcase) }"
OPが求めていたものではありませんが、このページで見つけたいと思っていたものです。
ファイルをURLに似た名前に変更するための「slugify」バージョン
(つまり、英数字、ドット、ダッシュのみを含む):
rename "s/[^a-zA-Z0-9\.]+/-/g" filename
組版を提案する人はいませんか?
typeset -l new # always lowercase
find $topPoint | # not using xargs to make this more readable
while read old
do mv "$old" "$new" # quotes for those annoying embedded spaces
done
Git bashのようなWindowsエミュレーションでは、Windowsはフードの下で大文字と小文字を区別しないため、これは失敗する可能性があります。これらの場合、最初に「$ old.tmp」などの別の名前にファイルをmvするステップを追加し、次に$ newに追加します。