ফাইলগুলি পুনরায় নামকরণে সেড ব্যবহার করে Using


89

উদ্দেশ্য

এই ফাইলের নামগুলি পরিবর্তন করুন:

  • F00001-0708-আরজি-বিসলিউড
  • F00001-0708-CS-akgdlaul
  • F00001-0708-ভিএফ-হিউলজিগল

এই ফাইলের নামগুলিতে:

  • F0001-0708-আরজি-বিসলিউড
  • F0001-0708-CS-akgdlaul
  • F0001-0708-ভিএফ-হিউলজিগল

শেল কোড

পরীক্ষা করার জন্য:

ls F00001-0708-*|sed 's/\(.\).\(.*\)/mv & \1\2/'

করতে:

ls F00001-0708-*|sed 's/\(.\).\(.*\)/mv & \1\2/' | sh

আমার প্রশ্ন

আমি সেড কোড বুঝতে পারি না। প্রতিস্থাপনের আদেশ কী তা আমি বুঝতে পারি

$ sed 's/something/mv'

মানে। এবং আমি নিয়মিত ভাবগুলি কিছুটা বুঝি। তবে আমি বুঝতে পারি না এখানে কী ঘটছে:

\(.\).\(.*\)

বা এখানে:

& \1\2/

প্রাক্তনটি আমার কাছে কেবল দেখতে এর অর্থ হ'ল: "একটি একক অক্ষর, তার পরে একটি একক অক্ষর, তার পরে কোনও একক চরিত্রের দৈর্ঘ্য ক্রম" - তবে অবশ্যই এর চেয়ে আরও কিছু আছে। যতদূর উত্তর অংশ:

& \1\2/

আমার কোন ধারণা নাই.


আরও দেখুন:
সেড

উত্তর:


152

প্রথমত, আমার বলা উচিত যে এটি করার সহজতম উপায় হ'ল প্রাক-নাম বা পুনরায় নাম কমান্ডগুলি ব্যবহার করা।

উবুন্টুতে, ওএসএক্স (হোমব্রিউ প্যাকেজ rename, ম্যাকপোর্টস প্যাকেজ p5-file-rename) বা পার্ল নাম (পূর্ব নাম) সহ অন্যান্য সিস্টেমে:

rename s/0000/000/ F0000*

অথবা ইউএস-লিনাক্স-এনজি থেকে নাম পরিবর্তন করা সিস্টেমগুলিতে যেমন আরএইচইএল:

rename 0000 000 F0000*

এটি সমমানের সেড কমান্ডের চেয়ে অনেক বেশি বোধগম্য।

তবে সেড কমান্ড বোঝার জন্য, সেড ম্যানপেজটি সহায়ক। যদি আপনি ম্যান সেড চালনা করেন এবং & এর জন্য অনুসন্ধান করেন (অনুসন্ধানের জন্য / কমান্ড ব্যবহার করে), আপনি এটি s / foo / বার / প্রতিস্থাপনে একটি বিশেষ চরিত্র পাবেন।

  s/regexp/replacement/
         Attempt  to match regexp against the pattern space.  If success‐
         ful,  replace  that  portion  matched  with  replacement.    The
         replacement may contain the special character & to refer to that
         portion of the pattern space  which  matched,  and  the  special
         escapes  \1  through  \9  to refer to the corresponding matching
         sub-expressions in the regexp.

সুতরাং, \(.\)প্রথম চরিত্রের সাথে মেলে যা রেফারেন্স করা যেতে পারে \1। তারপরে .পরবর্তী অক্ষরের সাথে মেলে যা সর্বদা 0 থাকে। তারপরে \(.*\)বাকী ফাইলের সাথে মেলে, যা উল্লেখ করা যেতে পারে \2

প্রতিস্থাপনের স্ট্রিং এটি সমস্তকে একসাথে রাখে &(মূল ফাইলের নাম) এবং \1\2এটি ফাইলের প্রতিটি অংশ যা 2 য় অক্ষর ব্যতীত, যা 0 ছিল।

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

ls F00001-0708-*|sed 's/F0000\(.*\)/mv & F000\1/' | sh

S / অনুসন্ধান / প্রতিস্থাপনে আসলে কী পরিবর্তন হচ্ছে তা দেখতে সক্ষম হওয়ায় এটি আরও বেশি পাঠযোগ্য। এছাড়াও যদি আপনি দুর্ঘটনাক্রমে দু'বার বা অন্য কোনও কিছু চালনা করেন তবে এটি আপনার ফাইলের বাইরে অক্ষরগুলি চুষতে থাকবে না।


4
আমার আরএইচইএল সার্ভারে, সিনট্যাক্সটির পুনরায় নামকরণ হবে "পুনর্নামকরণ 0000 000 F0000 *"
ডেভিড লেবাউর

4
সম্ভবত এটি renameনিজেই একটি "নাম পরিবর্তিত" লিঙ্ক। অর্থাৎ উবুন্টু: আউটপুটস ... থেকে "নতুন নামকরণ"rename করা হয়েছে ... ডেভিড দ্বারা উল্লিখিত সম্পূর্ণ ভিন্ন একটি প্রোগ্রাম। prenamereadlink -f $(which rename)/usr/bin/prenamerename
পিটার.ও

4
ভাল কথা, পিটার। পুনরায় নামকরণের ইউটিলিটিগুলির জন্য আমি উত্তর আপডেট করেছি।
এডওয়ার্ড অ্যান্ডারসন

4
এটি ডিবাগ করতে, পাইপটি শেষে sh এ সরান। কমান্ডগুলি স্ক্রিনে প্রতিধ্বনিত হবে।
বেন ম্যাথিউজ

4
আপনি কি নিশ্চিত যে পাইপ এলোমেলো ডেটা দেওয়ার জন্য একটি ভাল পরামর্শ sh? এটি সম্ভাব্য বিপজ্জনক কারণ স্বেচ্ছাসেবক কোড কার্যকর করা যায় (আপনি ডেটাটিকে কোড হিসাবে গণ্য করছেন)।
gniourf_gniourf

46

আপনার সিডের ব্যাখ্যাটি ছিল, এখন আপনি কেবল শেলটি ব্যবহার করতে পারেন, বাহ্যিক আদেশের প্রয়োজন নেই

for file in F0000*
do
    echo mv "$file" "${file/#F0000/F000}"
    # ${file/#F0000/F000} means replace the pattern that starts at beginning of string
done

4
দুর্দান্ত তবে আপনি প্রথম বন্ধনীর সাথে রেফারেন্স করতে পারবেন না।
লিওনিডাস স্যাম্প্রোস

28

আমি sedকয়েক বছর আগে ব্যাচটির নাম পরিবর্তন করে উদাহরণ সহ একটি ছোট পোস্ট লিখেছিলাম :

http://www.guyrutenberg.com/2009/01/12/batch-renaming-used-sed/

উদাহরণ স্বরূপ:

for i in *; do
  mv "$i" "`echo $i | sed "s/regex/replace_text/"`";
done

Regex গ্রুপ (যেমন থাকে \(subregex\) তাহলে আপনি তাদের যেমন প্রতিস্থাপন টেক্সট ব্যবহার করতে পারেন \1\, \2ইত্যাদি


মনে রাখবেন যে লিঙ্ক-কেবল উত্তর নিরুৎসাহিত করা হয় (লিঙ্কগুলি সময়ের সাথে সাথে বাসি হয়ে যায়)। আপনার উত্তর সম্পাদনা এবং এখানে একটি সংক্ষিপ্ত যোগ করুন দয়া করে বিবেচনা করুন।
ক্লিওপাত্র

যে দক্ষ নয়, কয়েক শতাধিক ফাইলের জন্য কাজটি সম্পন্ন করে। উত্সাহিত।
বরুণ চান্দক

23

সবচেয়ে সহজ উপায় হ'ল:

for i in F00001*; do mv "$i" "${i/F00001/F0001}"; done

বা, বহনযোগ্যভাবে,

for i in F00001*; do mv "$i" "F0001${i#F00001}"; done

এটি F00001ফাইলের নামের সাথে উপসর্গটি প্রতিস্থাপন করে F0001। এখানে মহেশের কাছে ক্রেডিট: http://www.debian-administration.org/articles/150


4
আপনার ভেরিয়েবল ইন্টারপোলেশনগুলি সঠিকভাবে উদ্ধৃত করা উচিত; mv "$i" "${i/F00001/F0001}"। তবে +1
ট্রিপল

7

sedহুকুম

s/\(.\).\(.*\)/mv & \1\2/

প্রতিস্থাপন মানে:

\(.\).\(.*\)

সঙ্গে:

mv & \1\2

ঠিক নিয়মিত sedআদেশ হিসাবে। তবে প্রথম বন্ধনী &এবং \nচিহ্নিতকারীরা এটিকে কিছুটা পরিবর্তন করে।

অনুসন্ধানের স্ট্রিং মেলে (এবং প্যাটার্ন 1 হিসাবে স্মরণ করা হয়) শুরুতে একক অক্ষর এবং তারপরে একটি একক অক্ষর, বাকী স্ট্রিং দ্বারা অনুসরণ করা (প্যাটার্ন 2 হিসাবে স্মরণ করা হয়)।

প্রতিস্থাপনের স্ট্রিংয়ে, আপনি প্রতিস্থাপনের অংশ হিসাবে ব্যবহার করতে এই মিলিত প্যাটার্নগুলি উল্লেখ করতে পারেন। আপনি সম্পূর্ণ মিলিত অংশ হিসাবে উল্লেখ করতে পারেন &

সুতরাং সেই sedআদেশটি যা করছে তা হ'ল mvমূল ফাইল (উত্সের জন্য) এবং 1 এবং 3 অক্ষরের উপর ভিত্তি করে একটি কমান্ড তৈরি করা হচ্ছে, কার্যকরভাবে অক্ষর 2 (গন্তব্যের জন্য) অপসারণ করা। এটি আপনাকে নীচের ফর্ম্যাটটিতে একটি লাইন দেয়:

mv F00001-0708-RG-biasliuyda F0001-0708-RG-biasliuyda
mv abcdef acdef

ইত্যাদি।


4
এটি একটি ভাল ব্যাখ্যা ছিল, তবে আপনি কীভাবে অন্যান্য কমান্ডের সাহায্যে ফাইলগুলি পুনরায় নামকরণ করতে সেড কমান্ডটি ব্যবহার করবেন তা উল্লেখ করা কার্যকর হবে। উদাহরণস্বরূপ:ls | sed "s/\(.\).\(.*\)/mv & \1\2/" | bash
jcarballo

@ জাকার্বালো: পার্স করা ls, পাইপ দিয়ে sedএবং তারপরে শেল দিয়ে পাইপ দেওয়া বিপজ্জনক ! এটি জাল ফাইলের নাম সহ স্বেচ্ছাসেবক কোড কার্যকর করার বিষয়। সমস্যাটি হ'ল ডেটাটিকে ডেটা হিসাবে বিবেচনা করা উচিত, এবং এখানে এটি কোনওরকম সতর্কতা ছাড়াই কোডে সিরিয়ালযুক্ত করা হয়। আমি আশা করি প্যাক্সিয়াব্লো এই উত্তরটি মুছে ফেলতে পারে কারণ এটি সত্যিই ভাল অনুশীলন দেখায় না। (আমি এই প্রশ্নে হোঁচট খেয়েছি কারণ একটি শিক্ষানবিশ এলোমেলোভাবে | shএকটি কমান্ডের পরে পাইপ করেছিল যা কাজ করে না এবং এই প্রশ্নটি দেখে এবং উত্তরগুলি ভেবে দেখেছিল যে এটি আরও ভাল কাজ করবে - আমি ভীত হই!) :)
gniourf_gniourf

3

ব্যাকস্ল্যাশ-পেরেন স্টাফের অর্থ, "প্যাটার্নটি মিলে যাওয়ার সময়, এখানে মেলে এমন স্টাফটি ধরে রাখুন" " পরে, প্রতিস্থাপন পাঠ্যের পাশে, আপনি সেই স্মরণ করা টুকরোগুলি "\ 1" (প্রথম প্রথম বন্ধনী ব্লক), "\ 2" (দ্বিতীয় ব্লক), এবং আরও কিছু দিয়ে ফিরে পেতে পারেন।


1

আপনি যদি সত্যিই যা করছেন সবগুলিই দ্বিতীয় চরিত্রটি সরিয়ে দিচ্ছে তা নির্বিশেষে, আপনি এটি করতে পারেন:

s/.//2

তবে আপনার কমান্ড একটি mvকমান্ড তৈরি করছে এবং কার্যকর করার জন্য শেলটিতে এটি পাইপ করছে।

এটি আপনার সংস্করণ ছাড়া আর পঠনযোগ্য নয়:

find -type f | sed -n 'h;s/.//4;x;s/^/mv /;G;s/\n/ /g;p' | sh

চতুর্থ অক্ষরটি সরানো হয়েছে কারণ find"./" দিয়ে প্রতিটি ফাইলের নাম প্রস্তুত করা হচ্ছে।


আমি আশা করি আপনি এই উত্তরটি মুছতে পারতেন। যদিও এটি ওপির খুব নির্দিষ্ট ক্ষেত্রে খুব ভাল ছিল, প্রচুর লোক এর উত্তর দেখতে | shপেয়েছে এবং এটি বুঝতে পারে না, এবং এলোমেলোভাবে একটি কমান্ডের পরে কাজ করবে না এই আশায় যে এটি কার্যকর হবে উত্তম. ভয়াবহ! (এবং তদতিরিক্ত, এটি ভাল অনুশীলন নয়)। আমি আশা করি আপনি বুঝতে পারবেন!
gniourf_gniourf

1

পার্লের পুনর্নামকরণ ( সরঞ্জামবক্সে একটি অবশ্যই থাকতে হবে ) ব্যবহার করে:

rename -n 's/0000/000/' F0000*

-nযখন আউটপুট বাস্তবের পুনরায় নামকরণ করতে ভাল দেখায় স্যুইচ সরান ।

সতর্কতা একই নামের অন্যান্য সরঞ্জাম রয়েছে যা এটি করতে সক্ষম হতে পারে বা নাও পারে, তাই সাবধান হন।

পুনরায় নাম কমান্ড যা util-linuxপ্যাকেজের অংশ , তা করবে না।

আপনি যদি নিম্নলিখিত কমান্ডটি চালনা করেন ( GNU)

$ rename

এবং আপনি দেখুন perlexpr, তাহলে এটি সঠিক সরঞ্জাম বলে মনে হচ্ছে।

যদি তা না হয় তবে এটিকে ডিফল্ট (সাধারণত ইতিমধ্যে কেস) তৈরি করতে Debianএবং ডেরাইভেটিভের মতো Ubuntu:

$ sudo apt install rename
$ sudo update-alternatives --set rename /usr/bin/file-rename

আর্চলিনাক্সের জন্য:

pacman -S perl-rename

রেডহ্যাট-পরিবার ডিস্ট্রোসের জন্য:

yum install prename

'Prename' প্যাকেজের মধ্যে হয় EPEL সংগ্রহস্থল।


জেন্টুর জন্য:

emerge dev-perl/rename

* বিএসডি এর জন্য:

pkg install gprename

বা p5-File-Rename


ম্যাক ব্যবহারকারীদের জন্য:

brew install rename

অন্য ডিস্ট্রোর সাথে যদি আপনার এই আদেশ না থাকে তবে এটি ইনস্টল করতে আপনার প্যাকেজ ম্যানেজারটি অনুসন্ধান করুন বা ম্যানুয়ালি করুন :

cpan -i File::Rename

পুরানো স্ট্যান্ডেলোন সংস্করণটি এখানে পাওয়া যাবে


মানুষের নাম পরিবর্তন


এই সরঞ্জামটি মূলত পার্লের বাবা ল্যারি ওয়াল লিখেছিলেন।


0

প্রথম বন্ধনীগুলি ব্যাকস্ল্যাশ সংখ্যা দ্বারা ব্যবহারের জন্য নির্দিষ্ট স্ট্রিং ক্যাপচার করে।


0
 ls F00001-0708-*|sed 's|^F0000\(.*\)|mv & F000\1|' | bash

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

0

আমি কি করব তা এখানে:

for file in *.[Jj][Pp][Gg] ;do 
    echo mv -vi \"$file\" `jhead $file|
                           grep Date|
                           cut -b 16-|
                           sed -e 's/:/-/g' -e 's/ /_/g' -e 's/$/.jpg/g'` ;
done

তারপরে যদি এটি ঠিক আছে, | shশেষ পর্যন্ত যুক্ত করুন। সুতরাং:

for file in *.[Jj][Pp][Gg] ;do 
    echo mv -vi \"$file\" `jhead $file|
                           grep Date|
                           cut -b 16-|
                           sed -e 's/:/-/g' -e 's/ /_/g' -e 's/$/.jpg/g'` ;
done | sh

0

কিছু উদাহরণ যা আমার পক্ষে কাজ করে:

$ tree -L 1 -F .
.
├── A.Show.2020.1400MB.txt
└── Some Show S01E01 the Loreming.txt

0 directories, 2 files

## remove "1400MB" (I: ignore case) ...

$ for f in *; do mv 2>/dev/null -v "$f" "`echo $f | sed -r 's/.[0-9]{1,}mb//I'`"; done;
renamed 'A.Show.2020.1400MB.txt' -> 'A.Show.2020.txt'

## change "S01E01 the" to "S01E01 The"
## \U& : change (here: regex-selected) text to uppercase;
##       note also: no need here for `\1` in that regex expression

$ for f in *; do mv 2>/dev/null "$f" "`echo $f | sed -r "s/([0-9] [a-z])/\U&/"`"; done

$ tree -L 1 -F .
.
├── A.Show.2020.txt
└── Some Show S01E01 The Loreming.txt

0 directories, 2 files
$ 

-1
for i in *; do mv $i $(echo $i|sed 's/AAA/BBB/'); done

4
তাই আপনাকে স্বাগতম। দয়া করে আপনার কোডের ব্যাখ্যা যোগ করুন consider এটি অন্যান্য ব্যবহারকারীদের এটি বুঝতে সহায়তা করবে।
দিগ্বিজয় এস

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