كيفية إعادة تسمية كافة الملفات والمجلدات إلى أحرف صغيرة على لينكس ؟
سؤال
يجب أن إعادة تسمية مجلد كامل الشجرة بشكل متكرر بحيث لا أحرف كبيرة تظهر في أي مكان (إنه C++ المصدرية ، ولكن هذا لا يهم).نقاط المكافأة تجاهل السير الذاتية و إس التحكم في الملفات/المجلدات.يفضل أن يكون وسيلة شيل منذ قذيفة ينبغي أن تكون متاحة في أي مربع لينكس.
كانت هناك بعض الحجج المقنعة عن تفاصيل إعادة تسمية الملف.
أعتقد الملفات مع نفس صغيرة الأسماء يجب أن تكون الكتابة إنها مشكلة المستخدم.عندما خرج على تجاهل ملف نظام الكتابة الأولى مع هذا الأخير أيضا.
وأود أن تنظر A-Z الحروف وتحويلها إلى a-z, كل شيء آخر هو مجرد الدعوة إلى مشاكل (على الأقل مع شفرة المصدر).
السيناريو سيكون من اللازم لتشغيل بناء على نظام لينكس ، لذلك أعتقد تغييرات السير الذاتية أو إس التحكم في ملفات يجب حذفها.بعد كل شيء, انها مجرد خدش الخروج.ربما "تصدير" هو أكثر ملاءمة.
المحلول
نسخة موجزة باستخدام "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+, سوف تحتاج إلى إضافة-و العلم
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
معظم الإجابات أعلاه هي خطرة لأنها لا تتعامل مع الأسماء التي تحتوي على الأحرف الفردية.الرهان الأكثر أمانا لهذا النوع من الشيء هو استخدام تجد هذا -print0 الخيار الذي سيتم إنهاء الملفات مع 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
...حسنا ماذا ...
يعمل هذا إذا كان لديك بالفعل أو إعداد إعادة تسمية الأوامر (على سبيل المثالمن خلال الشراب تثبيت في نظام التشغيل Mac):
rename --lower-case --force somedir/*
الرجل الذي يحب الرجال إلى تعقيد الأمور أكثر..
إعادة تسمية 'y/A-Z a-z/' *
وهذا يعمل على 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-لينكس, و هذا هو مختلفة غير متوافقة أداة)
باستخدام لاري الجدار اسم الملف المثبت
$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/'
(أين الإصلاح هو بالطبع السيناريو أعلاه)
السؤال الأصلي طلبت تجاهل إس والسير الذاتية الدلائل التي يمكن القيام به عن طريق إضافة -تقليم إلى العثور على الأوامر.E. g تجاهل السير الذاتية:
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 '{}' \;
إيان
هنا هو الحل الأمثل باستخدام باش قذيفة النصي:
#!/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 التحكم في الملفات داخل هذا المجلد لا تزال تسمية, للأسف).
تحرير:منذ "تجد العمق" و "العثور على | نوع -r" كل عودة قائمة المجلدات في استخدامها من أجل إعادة تسمية لا يفضل استخدام "العمق" للبحث في المجلدات.
هذا هو صغير قذيفة النصي الذي يفعل ما طلبت:
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
نلاحظ العمق في البحث.
سبق نشر العمل تماما في الخروج من مربع أو مع بعض التعديلات البسيطة الحالات ولكن هناك بعض الحالات التي قد تريد أن تأخذ في الاعتبار قبل تشغيل دفعة إعادة تسمية:
ما يجب أن يحدث إذا كان لديك اثنين أو أكثر من الأسماء في نفس المستوى في التسلسل الهرمي المسار التي تختلف فقط من القضية ، مثل
ABCdef
,abcDEF
وaBcDeF
?يجب إعادة تسمية سيناريو إجهاض أو مجرد تحذير و الاستمرار ؟كيف تعرف انخفاض حالة عدم US-ASCII الأسماء ؟ إن هذه الأسماء قد تكون موجودة ، يجب التحقق من واستبعاد تمريرة أن يؤديها أولا ؟
إذا كنت تقوم بتشغيل عملية إعادة تسمية على السير الذاتية أو إس عمل نسخ ، قد تفسد عمل نسخ إذا قمت بتغيير حالة على ملف أو دليل الأسماء.يجب أن السيناريو أيضا العثور على ضبط الإدارية الداخلية الملفات مثل .svn/مقالات أو CVS/المدخلات ؟
for f in `find -depth`; do mv ${f} ${f,,} ; done
find -depth
يطبع كل ملف و دليل مع دليل محتويات المطبوعة قبل الدليل نفسه. ${f,,}
lowercases اسم الملف.
مع ماك ،
تثبيت 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
ليس المحمولة ، Zsh فقط ، ولكن مختصر جدا.
أولا, تأكد من zmv
يتم تحميل.
autoload -U zmv
أيضا, تأكد من extendedglob
على:
setopt extendedglob
ثم استخدام:
zmv '(**/)(*)~CVS~**/CVS' '${1}${(L)2}'
أن متكرر صغيرة الملفات والدلائل أين اسم ليس السير الذاتية.
في OSX, mv -f يظهر "نفس الملف" خطأ لذا تسمية مرتين.
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
كنت بحاجة للقيام بذلك في سيغوين الإعداد على ويندوز 7 و وجدت أن لدي أخطاء في بناء الجملة مع اقتراحات من فوق التي حاولت (على الرغم من أنني قد غاب خيار العمل) لكن هذا الحل من مباشرة من ubutu المنتديات عملت من أن :-)
ls | while read upName; do loName=`echo "${upName}" | tr '[:upper:]' '[:lower:]'`; mv "$upName" "$loName"; done
( ملحوظة: كان في السابق محل بيضاء مع يؤكد باستخدام
for f in *\ *; do mv "$f" "${f// /_}"; done
وأود أن تصل الثعبان في هذه الحالة لتجنب بتفاؤل افتراض مسارات بدون مسافات أو مائلة.لقد وجدت أيضا أن 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])
طويلة ولكن "يعمل مع أي مفاجآت و لا منشآت"
هذا البرنامج النصي مقابض أسماء الملفات التي تحتوي على مسافات ونقلت الأخرى غير عادية أحرف Unicode يعمل على قضية حساسة أنظمة الملفات الأكثر Unix-y البيئات التي باش awk المثبتة (أيتقريبا كل).كما أن التقارير التصادم إذا أي (ترك الملف في أحرف كبيرة) و بالطبع تسمية كل من الملفات و الدلائل و يعمل بشكل متكرر.أخيرا انها للتكيف للغاية:يمكنك قرص الأمر تجد أن الهدف الملفات/تطبيق الاستعراض المفصل كنت ترغب يمكنك قرص 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
أبسط نهج وجدت على MacOSX استخدام تسمية حزمة من http://plasmasturm.org/code/rename/:
brew install rename
rename --force --lower-case --nows *
- قوة تسمية حتى عند ملف مع اسم الوجهة موجود بالفعل.
--أقل حدة تحويل أسماء الملفات إلى حالة انخفاض جميع.
--نوس استبدال كل تسلسل بيضاء في اسم الملف مع واحد الأحرف السفلية.
( 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 (حيث العمق غير متوفرة) ، ثم الملفات.ثم grep -v /CVS بدلا من تجد-تقليم لأن الأمر أبسط من ذلك.كبيرة الدلائل ، f في ... يمكن تجاوز بعض شل المخازن المؤقتة.استخدام تجد ...| حين قراءة لتجنب ذلك.
نعم, هذا سوف تضرب الملفات التي تختلف فقط في حالة...
Slugify تسمية (regex)
ليس بالضبط ما OP طلبت, ولكن ما كنت آمل أن تجد في هذه الصفحة:
و "slugify" نسخة لإعادة تسمية الملفات بحيث تكون مماثلة إلى عناوين url
(أيتشمل فقط أبجدية, النقاط, و شرطات):
rename "s/[^a-zA-Z0-9\.]+/-/g" filename
إذا كنت تستخدم قوس لينكس, يمكنك تثبيت 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 # substite string on pattern
--yes # Confirm all actions
يمكنك إحضار العينة المطورين.mp3 الملف من هنا, إذا لزم الأمر ;)
لا أحد يشير تنضيدها?
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
على ويندوز محاكاة مثل جيت باش وهذا قد تفشل بسبب ويندوز ليست القضية الحساسة تحت غطاء محرك السيارة.لأولئك, إضافة خطوة mv هذا الملف إلى اسم آخر أولا ، مثل "$القديمة.tmp" ، ثم إلى $جديد.
هذا يعمل بشكل جيد على ماك أيضا:
ruby -e "Dir['*'].each { |p| File.rename(p, p.downcase) }"
find . -depth -name '*[A-Z]*'|sed -n 's/\(.*\/\)\(.*\)/mv -n -v -T \1\2 \1\L\2/p'|sh
لم أحاول أكثر تفصيلا النصوص المذكورة هنا ، ولكن أيا من واحد فلكس الإصدارات عملت بالنسبة لي على ناس Synology. 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
هو المهم).
هذا comand في حد ذاته مفيد بشكل خاص العثور على الملفات التي تريد إعادة تسميتها في المقام الأول.استخدام هذا بعد استكمال تسمية الأمر إلى البحث عن الملفات التي لم يتم استبدالها بسبب اسم الملف التصادم أو أخطاء.
sed -n 's/\(.*\/\)\(.*\)/mv -n -v -T \1\2 \1\L\2/p'
هذا الجزء يقرأ ملفات أنتج من قبل find
و صيغ لهم في mv
الأمر باستخدام تعبير عادي.على -n
الخيار يتوقف sed
من الطباعة الإدخال ، p
الأمر في البحث و استبدال regex النواتج استبدال النص.
على regex نفسه يتكون من اثنين من الأسرى:الجزء حتى آخر / (الذي هو دليل من الملف) و اسم الملف نفسه.الدليل هو ترك سليمة ، ولكن اسم الملف تتحول إلى أحرف صغيرة.لذا ، إذا 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
أو أي قذيفة من ترضيك.