বাশ সহ বিশাল সংখ্যক চিত্র ফাইলের নামকরণ


16

আমার প্রায় নাম বদলানো দরকার। 70,000 ফাইল। উদাহরণস্বরূপ: থেকে sb_606_HBO_DPM_0089000থেকে sb_606_dpm_0089000ইত্যাদি

সংখ্যা পরিসীমা থেকে যায় 0089000থেকে 0163022। এটি নামের প্রথম অংশটিই পরিবর্তিত হওয়া দরকার। সমস্ত ফাইল একক ডিরেক্টরিতে থাকে এবং ক্রমান্বয়ে গণনা করা হয় (একটি চিত্র ক্রম)। সংখ্যাগুলি অপরিবর্তিত থাকতে হবে।

আমি যখন এটির চেষ্টা করার চেষ্টা করি তখন তা আমার কাছে গ্রিজ হয়ে যায় যে 'আর্গুমেন্টের তালিকাটি দীর্ঘ।'

সম্পাদনা:

আমি প্রথমে একটি একক ফাইলের নামকরণের চেষ্টা করেছি mv:

mv sb_606_HBO_DPM_0089000.dpx sb_606_dpm_0089000.dpx

তারপরে আমি একটি ব্যাপ্তির নাম বদলে দেওয়ার চেষ্টা করেছি (আমি এখানে গত সপ্তাহে শিখেছি কীভাবে ফাইলগুলির একটি লোড স্থানান্তরিত করতে হয়, তাই আমি ভেবেছিলাম যে একই সিনট্যাক্সগুলি ফাইলগুলির নাম পরিবর্তনের জন্য কাজ করতে পারে ...)। আমি মনে করি যে আমি নিম্নলিখিতগুলি (বা এর মতো কিছু) চেষ্টা করেছি:

mv sb_606_HBO_DPM_0{089000..163023}.dpx sb_606_dpm_0{089000..163023}.dpx

4
পর্যালোচকদের কাছে : আমি মনে করি এটি একটি সদৃশ নয়; বিপুল সংখ্যক ফাইল শেলের ARG_MAXসীমাবদ্ধতার সাথে সংঘর্ষের কারণে অন্যান্য প্রশ্নের বেশিরভাগ সিএলআই উত্তর এখানে কাজ করবে না । যেহেতু এই প্রশ্নটি স্পষ্টভাবে একটি কমান্ড-লাইন সমাধান চেয়েছে, (সম্ভবত সমান) জিইউআই সমাধানগুলি অন্য প্রশ্নের মতোও মেলে না।
মিষ্টান্ন

1
আমি মনে করি না এটি একটি ডুপ কারণ ফাইলের নাম পরিবর্তন সম্পর্কে একাধিক প্রশ্ন থাকা ঠিক আছে। আসুন জেনেরিক রিসোর্সের বিরুদ্ধে নির্দিষ্ট প্রশ্নগুলি বন্ধ না করা যাক যা আসলে তাদের উত্তর দেয় না ...
Zanna

1
@ রিচ আপনি কী আদেশটি স্পষ্টভাবে সম্পাদনা করতে পেরেছেন তা যদি বোঝা যায় তবে তা পরিষ্কার হয়ে যাবে যে এটি কোনও ডুপ নয়। (এটি আমাদের দেখায় যে আপনি এই পদ্ধতির বিষয়ে সচেতন)) চিয়ার্স।
স্পারহাক

2
ধনী, আপনার প্রশ্নটি কোনও ধূপ নয়, কারণ এটি একটি নির্দিষ্ট প্রশ্ন। এটা নিয়ে চিন্তা করবেন না। আরও গুরুত্বপূর্ণভাবে, কোনও প্রশ্ন বেশ কয়েকটি উত্সাহিত উত্তর পেয়ে যাওয়ার পরে এটি সম্পাদনা করা সম্ভবত ভাল ধারণা নয় কারণ আপনার সম্পাদনাগুলি বিদ্যমান উত্তরগুলি কম বৈধ করে তুলতে পারে। এখন আমার মনে হচ্ছে আমার উত্তরটির ব্যাখ্যা করা উচিত কেন mv {1..2} {3..4}কাজ করে না, যা সম্পূর্ণ ভিন্ন সমস্যা থেকে ARG_MAX... উত্তর দেওয়া প্রত্যেকে প্রত্যেকেই সম্ভবত একই বোধ করবে! সুতরাং, আমার দৃষ্টিকোণ থেকে, আমি আশা করি আপনি আপনার শেষ সম্পাদনাটি রোলব্যাক করবেন এবং আপনি যদি চান, তবে mvরেঞ্জগুলির সাথে
আইং

1
@ স্পারহাক ওপি প্রশ্নের প্রথম সংস্করণ থেকে বেশ স্পষ্টভাবে লিখেছেন যে সমস্যাটি argument list too longত্রুটি। আর পরিষ্কার করার দরকার নেই, এটি স্পষ্টতই দুপ নয়, কারণ আমাদের এআরজি_ম্যাক্সের সাথে কাজ করার জন্য একটি কার্যপ্রণালী প্রয়োজন এবং প্রস্তাবিত নকলের উত্তরগুলি এটি না করে।
টেরডন

উত্তর:


25

একটি উপায় হ'ল ব্যবহার findকরা -execএবং +বিকল্পটি। এটি একটি আর্গুমেন্ট তালিকা তৈরি করে তবে সর্বোচ্চ যুক্তি তালিকার তালিকা ছাড়িয়ে সমস্ত ফাইলের মধ্যে অপারেট করার জন্য প্রয়োজনীয় তালিকাটিকে তালিকায় ভেঙে দেয়। এটি উপযুক্ত যখন সমস্ত যুক্তি একই রকম হয়। renameনা হলেও এরকম ঘটনা ঘটে mv

পার্ল নাম পরিবর্তন করতে আপনার প্রয়োজন হতে পারে:

sudo apt install rename

তারপরে আপনি ব্যবহার করতে পারেন, উদাহরণস্বরূপ:

find . -maxdepth 1 -exec rename -n 's/_HBO_DPM_/_dpm_/' {} +

-nপ্রকৃতপক্ষে ফাইলগুলির নাম পরিবর্তন করতে, পরীক্ষার পরে সরান ।


11

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

mmv

আমি একই নামের প্যাকেজ থেকে এমএমভি কমান্ডটি ব্যবহার করব :

mmv '*HBO_DPM*' '#1dpm#2'

নোট করুন যে আর্গুমেন্টগুলি স্ট্রিং হিসাবে পাস হয়েছে, সুতরাং শেলবে গ্লোব সম্প্রসারণ ঘটে না। কমান্ডটি ঠিক দুটি আর্গুমেন্ট গ্রহণ করে এবং তারপরে ফাইলের সংখ্যার উপর কোন সীমাবদ্ধতা ছাড়াই অভ্যন্তরীণভাবে সম্পর্কিত ফাইলগুলি সন্ধান করে। এছাড়াও নোট করুন যে উপরের কমান্ডটি ধরে নিয়েছে যে প্রথম গ্লোবের সাথে মেলে সমস্ত ফাইলের নাম পরিবর্তন করা হবে। অবশ্যই আপনি আরও নির্দিষ্ট হতে পারেন:

mmv 'sb_606_HBO_DPM_*' 'sb_606_dpm_#1'

যদি আপনার একই ডিরেক্টরিতে অনুরোধ করা নম্বর সীমার বাইরে ফাইল থাকে তবে আপনি এই উত্তরটিতে আরও নীচে দেওয়া সংখ্যার লুপটি দিয়ে ভাল হতে পারেন। তবে আপনি উপযুক্ত প্যাটার্ন সহ এমএমভি আমন্ত্রণগুলির ক্রমটিও ব্যবহার করতে পারেন:

mmv 'sb_606_HBO_DPM_0089*'       'sb_606_dpm_0089#1'    # 0089000-0089999
mmv 'sb_606_HBO_DPM_009*'        'sb_606_dpm_009#1'     # 0090000-0099999
mmv 'sb_606_HBO_DPM_01[0-5]*'    'sb_606_dpm_01#1#2'    # 0100000-0159999
mmv 'sb_606_HBO_DPM_016[0-2]*'   'sb_606_dpm_016#1#2'   # 0160000-0162999
mmv 'sb_606_HBO_DPM_01630[01]?'  'sb_606_dpm_01630#1#2' # 0163000-0163019
mmv 'sb_606_HBO_DPM_016302[0-2]' 'sb_606_dpm_016302#1'  # 0163020-0163022

সংখ্যা উপর লুপ

আপনি যদি কোনও কিছু ইনস্টল করা এড়াতে চান বা এই ব্যাপ্তির বাইরে ম্যাচগুলি এড়িয়ে সংখ্যার পরিসরটি নির্বাচন করতে চান এবং আপনি 74,023 কমান্ডের অনুরোধের জন্য অপেক্ষা করতে প্রস্তুত থাকেন, আপনি একটি সরল বাশ লুপ ব্যবহার করতে পারেন:

for i in {0089000..0163022}; do mv sb_606_HBO_DPM_$i sb_606_dpm_$i; done

অনুক্রমের কোনও ফাঁক নেই বলে এখানে বিশেষ করে ভাল কাজ করে। অন্যথায় আপনি উত্স ফাইলটি আসলে আছে কিনা তা যাচাই করতে চাইতে পারেন।

for i in {0089000..0163022}; do
  test -e sb_606_HBO_DPM_$i && mv sb_606_HBO_DPM_$i sb_606_dpm_$i
done

নোট করুন যে for ((i=89000; i<=163022; ++i))বন্ধনী সম্প্রসারণের বিপরীতে কিছু বাশ কয়েক বছর আগে মুক্তি পেয়েছে বলে নেতৃস্থানীয় শূন্যগুলি পরিচালনা করে। আসলে আমি পরিবর্তনের জন্য অনুরোধ করেছি, তাই এর ব্যবহারের ক্ষেত্রে আমি খুশি see

আরও পড়ুন: বাশ তথ্য পৃষ্ঠাগুলিতে বিশেষত অংশটির ব্রেস প্রসারণ{x..y[..incr]}

ফাইল উপর লুপ

অন্য বিকল্পটি হ'ল কোনও উপযুক্ত গ্লোব দিয়ে লুপ করা উচিত, পরিবর্তে প্রশ্নের পূর্ণসংখ্যার ব্যাপ্তিটি কেবল লুপিংয়ের পরিবর্তে। এটার মতো কিছু:

for i in *HBO_DPM*; do mv "$i" "${i/HBO_DPM/dpm}"; done

আবার এটি mvপ্রতি ফাইলের জন্য একটি অনুরোধ। এবং আবার লুপটি উপাদানগুলির একটি দীর্ঘ তালিকার উপরে চলে গেছে, তবে পুরো তালিকাটি একটি সাবপ্রসেসের আর্গুমেন্ট হিসাবে পাস করা হয় না, তবে বাশ দ্বারা অভ্যন্তরীণভাবে পরিচালিত হয়, সুতরাং সীমাটি আপনাকে সমস্যার কারণ করবে না।

আরও পড়ুন: বাশ তথ্য পৃষ্ঠাগুলিতে শেল প্যারামিটার সম্প্রসারণ , ${parameter/pattern/string}অন্যদের মধ্যে ডকুমেন্টিং ।

আপনি যে সরবরাহ করেছেন তার মধ্যে যদি সংখ্যা সীমার সীমাবদ্ধ রাখতে চান, আপনি তার জন্য একটি চেক যোগ করতে পারেন:

for i in sb_606_HBO_DPM_+([0-9]); do
  if [[ "${i##*_*(0)}" -ge 89000 ]] && [[ "${i##*_*(0)}" -le 163022 ]]; then
    mv "$i" "${i/HBO_DPM/dpm}"
  fi
done

এখানে থেকে ${i##pattern}দীর্ঘতম উপসর্গটি মিলছে । সেই দীর্ঘতম উপসর্গটিকে কোনও কিছুর পরে আন্ডারস্কোর, তারপরে শূন্য বা আরও বেশি শূন্য হিসাবে সংজ্ঞায়িত করা হয়। পরবর্তীটি লিখিত হিসাবে এটি একটি বর্ধিত গ্লোব প্যাটার্ন যা বিকল্পটি সেট করা হচ্ছে তার উপর নির্ভর করে । শীর্ষস্থানীয় শূন্যগুলি সরিয়ে ফেলতে সংখ্যাটি বেস 10 হিসাবে নয় বলে বিবেচনা করা গুরুত্বপূর্ণ 8 লুপ আর্গুমেন্টে আরেকটি প্রসারিত গ্লোব, এক বা একাধিক সংখ্যার সাথে মিলে যাওয়া, যদি আপনার সেখানে ফাইলগুলি একই শুরু হয় তবে শেষ হয় না সংখ্যা।pattern$i*(0)extglob+([0-9])


ধন্যবাদ! এটি একটি স্বপ্নের মতো কাজ করেছে: আমার জন্য 89 0089000..0163022 in; do mv sb_606_HBO_DPM_ $ i sb_606_dpm_ $ i; সম্পন্ন - এটি কাজ করতে আমাকে ফাইলের নাম এক্সটেনশান যুক্ত করতে হয়েছিল, তবে এটি আমার যা ইচ্ছা তা করেছে এবং আমি বাক্য গঠনটিও বুঝতে পেরেছি। আপনাকে ধন্যবাদ @ এমভিজি
সমৃদ্ধ

@ রিচ: হ্যাপি আমি সাহায্য করতে পারি - আপনি এবং আশা করি ভবিষ্যতেও দর্শকরা। সর্বাধিক দরকারী উত্তর গ্রহণ করতে ভুলবেন না । ভবিষ্যতে যদি আরও ভাল কিছু আসে তবে আপনি সর্বদা সেই চেক চিহ্নটি পরিবর্তন করতে পারেন।
এমভিজি

10

ARG_MAXসীমাটি ঘিরে কাজ করার একটি উপায় হ'ল ব্যাশ শেলের বিল্টিন ব্যবহার করা printf:

printf '%s\0' sb_* | xargs -0 rename -n 's/HBO_DPM/dpm/'

যাত্রা।

rename -n 's/HBO_DPM/dpm/' sb_*
bash: /usr/bin/rename: Argument list too long

কিন্তু

printf '%s\0' sb_* | xargs -0 rename -n 's/HBO_DPM/dpm/'
rename(sb_606_HBO_DPM_0089000, sb_606_dpm_0089000)
.
.
.
rename(sb_606_HBO_DPM_0163022, sb_606_dpm_0163022)

7
find . -type f -exec bash -c 'echo $1 ${1/HBO_DPM/dpm}' _ {} \;
./sb_606_HBO_DPM_0089000 ./sb_606_dpm_0089000

find.সমস্ত ফাইলের জন্য বর্তমান ডিরেক্টরিতে -type fএবং একের পর এক$1 প্রতিস্থাপনের HBO_DPMসাথে পাওয়া ফাইলটির নতুন নামকরণ করুনdmp -exec ... \;

প্রতিস্থাপন echoসঙ্গে mvপুনঃনামকরণ সঞ্চালন।


6

আপনি একটু অজগর লিপি লিখতে পারেন, এরকম কিছু:

import os
for file in os.listdir("."):
    os.rename(file, file.replace("HBO_DPM", "dpm"))

যে rename.pyফোল্ডারে ফাইল রয়েছে সেই পাঠ্য ফাইল হিসাবে সেভ করুন , তারপরে সেই ফোল্ডারে টার্মিনাল দিয়ে যান:

python rename.py

6

আপনি ফাইল দিয়ে এটি ফাইল করতে পারেন (এটি কিছু সময় নিতে পারে)

sudo apt install util-linux  # if you don't have it already
for i in *; do rename.ul HBO_DPM dpm "$i"; done

ভালো লেগেছে পার্ল renameঅন্যান্য উত্তর ব্যবহৃত rename.ulএকটি বিকল্প থাকে -nবা --no-actপরীক্ষার জন্য।


আমি জানার উত্তর সম্পর্কে আপনার মন্তব্য সম্পাদনা করেছি, দয়া করে জান্নার উত্তর সম্পাদনা করুন বা একটি মন্তব্য দিন।
ফসলিনাক্স

@ বাবাশু যে আমার উত্তরের মন্তব্য ছিল না - এটি -nপরীক্ষার জন্য ব্যবহৃত পতাকাটিকে বোঝাচ্ছিল এবং এটি ব্যবহার করতে পারার পরামর্শ দিয়েছিলাম rename.ul
জান্না

3

আমি দেখছি যে কেউ আমার সেরা বন্ধুটিকে sedপার্টিতে আমন্ত্রণ জানায় নি :)। নিম্নলিখিত forলুপটি আপনার লক্ষ্য অর্জন করবে:

for i in sb_606_HBO_DPM*; do
  mv "$i" "$(echo $i | sed 's/HBO_DPM/dpm/')";
done

যেমন একটি কাজের জন্য অনেক সরঞ্জাম আছে, আপনার জন্য সবচেয়ে বোধগম্য একটি নির্বাচন করুন। এটি সাধারণ এবং সহজেই এই বা অন্যান্য উদ্দেশ্যে অনুসারে পরিবর্তন করা হয় ...


মঞ্জুর, এই সুনির্দিষ্ট ক্ষেত্রে খুব প্রাসঙ্গিক নয়, তবে যদি ফাইলের নামের কোনওটিতে নিউলাইন থাকে তবে এটি ব্যর্থ হবে। আমি এটি উল্লেখ করেছি যেহেতু বেশিরভাগ (সমস্ত?) অন্যান্য উত্তরগুলি দৃ are় এবং নির্বিচারে ফাইলের নামগুলি মোকাবেলা করতে পারে বা কেবল ওপি'র ফাইল নামকরণ প্রকল্পে কাজ করতে পারে।
টেরডন

... নিউলাইনস, স্পেসস, ওয়াইল্ডকার্ডস, ... যার কয়েকটি $iকমান্ড সাবস্টিটিউশনে উদ্ধৃতি দিয়ে এড়ানো যেতে পারে , তবে ফাইলনামে ট্রেলিং করা নতুন লাইন পরিচালনা করার সহজ উপায় নেই।
মুরু

3

যেহেতু আমরা বিকল্পগুলি দিচ্ছি, এখানে একটি পার্ল পদ্ধতির। cdলক্ষ্য ডিরেক্টরিতে চালনা করুন এবং রান করুন:

perl -e 'foreach(glob("sb_*")){rename $_, s/_HBO_DPM_/_dpm_/r}'

ব্যাখ্যা

  • perl -e: প্রদত্ত স্ক্রিপ্টটি চালান -e
  • foreach(glob){}: { }গ্লোব এর প্রতিটি ফলাফলের মধ্যে যা আছে তা চালান ।
  • glob("sb_*"): বর্তমান ডিরেক্টরিতে সমস্ত ফাইল এবং ডিরেক্টরিগুলির একটি তালিকা ফিরে আসুন যার নাম শেল গ্লোবের সাথে মেলে sb*
  • rename $_, s/_HBO_DPM_/_dpm_/r: পার্ল যাদু। $_একটি বিশেষ পরিবর্তনশীল যা প্রতিটি উপাদানকে ধরে রাখে যা আমরা পুনরাবৃত্তি করছি (এর মধ্যে foreach)। সুতরাং এখানে, এটি প্রতিটি ফাইল পাওয়া যাবে। s/_HBO_DPM_/_dpm_/এর _HBO_DPM_সাথে প্রথম ঘটনাকে প্রতিস্থাপন করে _dpm_। এটি $_ডিফল্টরূপে চালিত হয়, সুতরাং এটি প্রতিটি ফাইলের নামে চলবে। এর /rঅর্থ "এই প্রতিস্থাপনটি লক্ষ্যযুক্ত স্ট্রিংয়ের একটি অনুলিপি (ফাইলের নাম) এ প্রয়োগ করুন এবং পরিবর্তিত স্ট্রিংটি ফিরিয়ে দিন you' renameআপনি যা প্রত্যাশা করতেন তা করে: এটি ফাইলগুলির নাম পরিবর্তন করে So সুতরাং পুরো জিনিসটি বর্তমান ফাইলটির নামটি ( $_) এর সাথে নিজের নাম পরিবর্তন করে দেবে _HBO_DPM_দ্বারা প্রতিস্থাপিত _dpm_

আপনি একই জিনিসটি প্রসারিত (এবং আরও পাঠযোগ্য স্ক্রিপ্ট) হিসাবে লিখতে পারেন:

#! /usr/bin/env perl
use strict;
use warnings;

foreach my $fileName (glob("sb_*")){
  ## Copy the name to a new variable
  my $newName = $fileName;
  ## change the copy. $newName is now the changed version
  $newName =~ s/_HBO_DPM_/_dpm_/;
  ## rename
  rename $fileName, $newName;
}

1

আপনি যে ধরণের নামকরণের কল্পনা করছেন তার উপর নির্ভর করে একাধিক লাইনের সম্পাদনা সহ বিড়ির ব্যবহার সন্তোষজনক হতে পারে।
আপনার বিশেষ ক্ষেত্রে আপনি আপনার পাঠ্য সম্পাদকের সমস্ত লাইন নির্বাচন করতে পারেন এবং কয়েকটি কীস্ট্রোকের ফাইল নামগুলির _ " HBO" অংশটি সরিয়ে ফেলতে পারেন ।


হ্যাঁ, vi এর গ্লোবাল সন্ধান এবং প্রতিস্থাপন রয়েছে।
জেসেন

2
আপনি কি দয়া করে আপনার উত্তরটি প্রসারিত করতে পারেন এবং উদাহরণ দিয়ে দিতে পারেন কীভাবে ওপি'র লক্ষ্য অর্জন করতে হয় vidir?
মিষ্টান্ন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.