একটি ডিরেক্টরি অধীনস্থ সকল ডিরেক্টরি Lowercasing


12

আমি একটি ডিরেক্টরির অধীনে প্রত্যেক ডিরেক্টরি 'নাম ছোট হাতের অক্ষরে চাই। যা দিয়ে কমান্ড আমি যে কি করতে পারেন?

উত্তর:


10

সমস্ত ডিরেক্টরি এক স্তরে, বা পুনরাবৃত্তির সাথে?

Zsh

এক স্তর করুন:

autoload zmv
zmv -o-i -Q 'root/(*)(/)' 'root/${1:l}'

recursively:

zmv -o-i -Q 'root/(**/)(*)(/)' 'root/$1${2:l}'

ব্যাখ্যা: zmvপ্রদত্ত প্রতিস্থাপন টেক্সট অনুযায়ী নকশার সাথে মেলে এমন ফাইল renames। -o-iপাসের -iপ্রতিটি বিকল্প mvফণা অধীন কমান্ড (নীচে দেখুন)। প্রতিস্থাপন লেখা, $1, $2, ইত্যাদি প্যাটার্ন ধারাবাহিক আলাদা গ্রুপ আছে। **যাও recursively সমস্ত (সাব) * ডিরেক্টরি মানে। চূড়ান্ত (/)একটি আলাদা গ্রুপ নয় বরং একটি উল্লিখিত glob কোয়ালিফায়ার শুধুমাত্র ডিরেক্টরি মেলে অর্থ। ${2:l}ধর্মান্তরিত $2ছোট হাতের অক্ষরে।

সুবহ

এক স্তর করুন:

for x in root/*/; do mv -i "$x" "$(printf %s "$x" | tr '[:upper:]' '[:lower:]')"; done

চূড়ান্ত /পরিমিত ডিরেক্টরি থেকে ম্যাচিং, এবং mv -iতোলে একটি সংঘর্ষের ক্ষেত্রে নিশ্চিতকরণ জন্য জিজ্ঞাসা করুন। সরান -iএকটি সংঘর্ষের, এবং ব্যবহার ক্ষেত্রে ওপর দিয়েই লিখতে yes n | for …। না ব্যাক অনুরোধ করা কোনো পুনঃনামকরনের যে ধাক্কা লাগা হবে সঞ্চালন।

recursively:

find root/* -depth -type d -exec sh -c '
    t=${0%/*}/$(printf %s "${0##*/}" | tr "[:upper:]" "[:lower:]");
    [ "$t" = "$0" ] || mv -i "$0" "$t"
' {} \;

ব্যবহারের -depthনিশ্চিত করে যে গভীরভাবে নেস্টেড ডিরেক্টরি তাদের পূর্বপুরুষদের সামনে প্রক্রিয়া করা হয়। নাম প্রক্রিয়াকরণ একটা হচ্ছে উপর নির্ভর /; যদি আপনি বর্তমান ডিরেক্টরির মধ্যে অপারেট কল করতে চান, ব্যবহার ./*(অভিযোজিত শেল স্ক্রিপ্ট সঙ্গে মানিয়ে নিতে .বা *পাঠকদের জন্য একটি ব্যায়াম যেমন ছেড়ে দেওয়া হয়)।

পার্ল পুনঃনামকরণ

এখানে আমি পার্ল পুনঃনামকরণ স্ক্রিপ্ট ব্যবহার করে উবুন্টু এবং ডেবিয়ান জাহাজ /usr/bin/prename(সাধারণত হিসাবে উপলব্ধ renameপাশাপাশি)। এক স্তর করুন:

rename 's!/([^/]*/?)$!\L/$1!' root/*/

Recursively, ব্যাশ ≥4 বা zsh সঙ্গে

shopt -s globstar  # only in bash
rename 's!/([^/]*/?)$!\L/$1!' root/**/*/

Recursively, portably:

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

OS X এর উপর অন্তত এই যদি থাকে ডিরেক্টরি ইতিমধ্যে ছোট হাতের হয় ব্যর্থ হবে: mv -i a aদিন "এমভি: অবৈধ যুক্তি: একটি / একটি করার জন্য একটি নামান্তর"।
জানুস

@Janus: রাইট, আপনি একটি ত্রুটির বার্তা, যা কুশ্রী পেতে (যদিও কমান্ড লাইনে নিরীহ)। কিন্তু যা হোক আমার ব্যবহৃত zmv, যা এই ক্ষেত্রে যত্ন নেয় থাকা উচিত।
গিলেজ 'SO- স্টপ হচ্ছে মন্দ'

আমি তখন প্রায় পাওয়া -execdirযা দুর্দান্ত: unix.stackexchange.com/questions/5412/... আমি তখন পাওয়া এটি কিছু আছে যা PATHপাগলামি এবং দু: খিত :-( ছিল
সিরো Santilli新疆改造中心法轮功六四事件

4

সেখানে একটি কমান্ডের যে কি করবে না, কিন্তু আপনি ভালো কিছু করতে পারেন:

for fd in */; do
  #get lower case version
  fd_lower=$(printf %s "$fd" | tr A-Z a-z)
  #if it wasn't already lowercase, move it.
  [ "$fd" != "$fd_lower" ] && mv "$fd" "$fd_lower"
done

আপনি এটা শক্তসমর্থ হতে হবে, তাহলে আপনি ইতিমধ্যেই দুই ডিরেক্টরি যেটি শুধুমাত্র ক্ষেত্রে ভিন্ন জন্য অ্যাকাউন্ট করা উচিত নয়।

একটি এক মাছ ধরার নৌকা হিসাবে:

for fd in */; do fd_lower=$(printf %s "$fd" | tr A-Z a-z) && [ "$fd" != "$fd_lower" ] && mv "$fd" "$fd_lower"; done

আমার লেখার মাধ্যমে এই Midway (মূলত একই) পরামর্শ আপ দেখিয়েছেন:for file in * ; do if [ -d "$file" ] ; then dest="$(echo $file | sed y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/)" ; [ "$dest" != "$file" ] && mv "$file" "$dest" ; fi ; done
frabjous

আমি এটা দিয়ে কাজ করার চেষ্টা ছিল find -type d, কিন্তু বেশ বুঝে উঠতে পারতাম না
মাইকেল Mrozek

1
আমার প্রবৃত্তি করতে পারতাম for fd in */;এইভাবে চেক জন্য প্রয়োজন এড়ানো যদি এটি একটি ডিরেক্টরির ছিলেন, কিন্তু আমি কোন ধারণা আছে এই প্রবৃত্তি একটি ভাল ছিল।
স্টিভেন ডি

হাঁ, জন্য ... * / ভাল হবে।
শন জে গফের

1
@Shawn: trইতিমধ্যে একটি সীমার আশা তাই tr '[A-Z]' '[a-z]'অনুবাদ করে [করতে [এবং ]করতে ]পার না। এটি অকেজো তবে ক্ষতিহীন; তবে উদ্ধৃতি চিহ্ন বিনা শেল বন্ধনী প্রসারিত হবে যদি বর্তমান ডিরেক্টরির মধ্যে একটি এক বড় হাতের অক্ষর নামের একটি ফাইল ছিল।
গিলস 'তাই মন্দ হওয়া বন্ধ করুন'

0

আমি এক-লাইনের চ্যালেঞ্জ :) প্রথমত, একটি পরীক্ষা ক্ষেত্রে প্রতিষ্ঠা হিসেবে এই নেন:

$ for d in foo Bar eVe; do mkdir -p dcthis/$d; touch dcthis/a${d}.txt; done
$ ls dcthis/
Bar     aBar.txt    aeVe.txt    afoo.txt    eVe     foo

আমি ব্যবহার findবড়হাতের অক্ষর সঙ্গে ডিরেক্টরি স্পট এবং তারপর এর মাধ্যমে তাদের downcase । অনুমান করার চেষ্টাটি কিছুটা হ্যাক-ইশ, তবে আমি যখন সরাসরি জিনিসগুলি পালানোর চেষ্টা করি তখন আমার মাথা সর্বদা বিস্ফোরিত হয়।sh -c 'mv {} echo {} | tr [:upper:] [:lower:]'sh -cfind

$ (cd dcthis && find . -maxdepth 1 -type d -path '*[A-Z]*' -exec sh -c 'mv {} `echo {} | tr [:upper:] [:lower:]`' \;)
$ ls dcthis/
aBar.txt    aeVe.txt    afoo.txt    bar     eve     foo

সতর্ক থাকুন: এই সমাধান দুর্ঘটনায় বিশালাকার downcasing কিনা পরীক্ষা করে না!


দুর্ঘটনায় পরীক্ষা করার সহজ: mv -i। একটি বড় সমস্যা যে আপনি মূল্য উদ্ধৃতি সঠিক ব্যবহার করেন নি তাই যদি সেখানে বিশেষ অক্ষর (হোয়াইটস্পেস বা হয় আপনার কমান্ড ব্যর্থ হবে \[*?) নামে যে কোন জায়গায়। ব্যবহারের কোন বিন্দু আছে find, যদি না recursing, এবং তারপর আপনার যা দরকার find -depth, এবং -pathহতে হবে -name। কাজ উদাহরণের জন্য আমার উত্তর দেখুন।
গিলেজ 'SO- স্টপ হচ্ছে মন্দ'

@Giles। ধন্যবাদ! আমি দেখেছি আপনার mv -iএই লেখার পর। উদ্ধৃতি দিয়ে ভাল পয়েন্ট ...
জানুস

0

find -execdir| পুনঃনামকরণ

এই এটা করতে হলে আপেক্ষিক পাথ উন্মাদ না থাকত সবচেয়ে ভালো উপায় হবে যেমন শুধুমাত্র basename কাজ করার জন্য পার্ল Regex ফু এড়াতে:

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

-execdirপ্রথম cdশুধুমাত্র basename উপর চালানোর আগে ডিরেক্টরির মধ্যে s।

দুর্ভাগ্যবশত, আমি যে পরিত্রাণ পেতে পারেন না PATHফাটান অংশ, find -execdirআপনি একটি আপেক্ষিক পথ থাকতে কিছু করতে রাজি PATH...: /ubuntu/621132/why-using-the-execdir-action- is-অনিরাপদ-জন্য-ডিরেক্টরি যা-is-ইন-দ্য-পাথ / 1109378 # 1109378

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.