كيفية إعادة تسمية كافة الملفات والمجلدات إلى أحرف صغيرة على لينكس ؟

StackOverflow https://stackoverflow.com/questions/152514

  •  02-07-2019
  •  | 
  •  

سؤال

يجب أن إعادة تسمية مجلد كامل الشجرة بشكل متكرر بحيث لا أحرف كبيرة تظهر في أي مكان (إنه C++ المصدرية ، ولكن هذا لا يهم).نقاط المكافأة تجاهل السير الذاتية و إس التحكم في الملفات/المجلدات.يفضل أن يكون وسيلة شيل منذ قذيفة ينبغي أن تكون متاحة في أي مربع لينكس.

كانت هناك بعض الحجج المقنعة عن تفاصيل إعادة تسمية الملف.

  1. أعتقد الملفات مع نفس صغيرة الأسماء يجب أن تكون الكتابة إنها مشكلة المستخدم.عندما خرج على تجاهل ملف نظام الكتابة الأولى مع هذا الأخير أيضا.

  2. وأود أن تنظر A-Z الحروف وتحويلها إلى a-z, كل شيء آخر هو مجرد الدعوة إلى مشاكل (على الأقل مع شفرة المصدر).

  3. السيناريو سيكون من اللازم لتشغيل بناء على نظام لينكس ، لذلك أعتقد تغييرات السير الذاتية أو إس التحكم في ملفات يجب حذفها.بعد كل شيء, انها مجرد خدش الخروج.ربما "تصدير" هو أكثر ملاءمة.

هل كانت مفيدة؟

المحلول

نسخة موجزة باستخدام "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

نلاحظ العمق في البحث.

سبق نشر العمل تماما في الخروج من مربع أو مع بعض التعديلات البسيطة الحالات ولكن هناك بعض الحالات التي قد تريد أن تأخذ في الاعتبار قبل تشغيل دفعة إعادة تسمية:

  1. ما يجب أن يحدث إذا كان لديك اثنين أو أكثر من الأسماء في نفس المستوى في التسلسل الهرمي المسار التي تختلف فقط من القضية ، مثل ABCdef, abcDEF و aBcDeF?يجب إعادة تسمية سيناريو إجهاض أو مجرد تحذير و الاستمرار ؟

  2. كيف تعرف انخفاض حالة عدم US-ASCII الأسماء ؟ إن هذه الأسماء قد تكون موجودة ، يجب التحقق من واستبعاد تمريرة أن يؤديها أولا ؟

  3. إذا كنت تقوم بتشغيل عملية إعادة تسمية على السير الذاتية أو إس عمل نسخ ، قد تفسد عمل نسخ إذا قمت بتغيير حالة على ملف أو دليل الأسماء.يجب أن السيناريو أيضا العثور على ضبط الإدارية الداخلية الملفات مثل .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

لا أحد يشير تنضيدها?

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 أو أي قذيفة من ترضيك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top