কিভাবে গ্রেপ এবং প্রতিস্থাপন


251

আমি পুনরাবৃত্তভাবে একটি ডিরেক্টরিতে সমস্ত ফাইল এবং উপ-ডিরেক্টরিগুলির মধ্যে একটি নির্দিষ্ট স্ট্রিং অনুসন্ধান করতে এবং এই স্ট্রিংটিকে অন্য স্ট্রিংয়ের সাথে প্রতিস্থাপন করতে হবে।

আমি জানি যে এটির আদেশটি এটির মতো দেখতে পাওয়া যেতে পারে:

grep 'string_to_find' -r ./*

তবে আমি কীভাবে প্রতিটি প্রতিস্থাপনকে string_to_findঅন্য স্ট্রিংয়ের সাথে প্রতিস্থাপন করতে পারি ?


আমি বিশ্বাস করি না গ্রেপ এটি করতে পারে (আমি ভুল হতে পারি)। প্রতিস্থাপনটি করার জন্য সহজ উপায়গুলি হবে সেড বা পার্ল ব্যবহার করা
মেমেন্টো মরি

2
ব্যবহার করার চেষ্টা করুনsed -i 's/.*substring.*/replace/'
এডি_ইম

2
@ এডি_ইম এটি প্রতিস্থাপনের সাথে পুরো লাইনটি প্রতিস্থাপন করবে। সাবস্ট্রিংয়ের আগে এবং পরে লাইনের অংশটি ক্যাপচার করতে আপনাকে গ্রুপিং ব্যবহার করতে হবে এবং তারপরে প্রতিস্থাপন লাইনে এটি স্থাপন করতে হবে। sed -i 's/\(.*\)substring\(.*\)/\1replace\2/'
JStrahl


উত্তর:


248

অন্য বিকল্পটি হ'ল সন্ধানটি ব্যবহার করা এবং তারপরে সেডটি দিয়ে।

find /path/to/files -type f -exec sed -i 's/oldstring/new string/g' {} \;

34
ওএস এক্স ১০.১০ টার্মিনালে, প্যারামিটারে একটি উপযুক্ত এক্সটেনশন স্ট্রিং -iপ্রয়োজনীয়। উদাহরণস্বরূপ, find /path/to/files -type f -exec sed -i "" "s/oldstring/new string/g" {} \;যাইহোক, খালি স্ট্রিং সরবরাহ করা ম্যানুয়ালটিতে বর্ণিত ভিন্ন হিসাবে একটি ব্যাকআপ ফাইল তৈরি করে ...
Eonil

10
আমি কেন "সেড: আরই ত্রুটি: অবৈধ বাইট সিকোয়েন্স" পাব। এবং হ্যাঁ, আমি -i ""ওএস এক্স এর জন্য যুক্ত করেছি It এটি অন্যথায় কাজ করে।
টাকো

2
আমার কাছে ম্যাকোএস 10.12 এ অবৈধ বাইট সিকোয়েন্স ইস্যু ছিল এবং এই প্রশ্ন / উত্তরটি আমার সমস্যার সমাধান করেছে: stackoverflow.com/questions/19242275/…
abeboparebop

3
এটি প্রতিটি ফাইলকে স্পর্শ করে তাই ফাইলের সময় সংশোধন করা হয়; এবং ধর্মান্তরিত থেকে শেষা w শ লাইন CRLFথেকে LFWindows এ।
jtw

183

আমি উত্তর পেয়েছি।

grep -rl matchstring somedir/ | xargs sed -i 's/string1/string2/g'

14
এটি দু'বার মিলে যাওয়া ফাইলগুলির মাধ্যমে একবার স্ক্যান করে ... একবার দিয়ে grepএবং তারপরে আবার sedfindপদ্ধতি ব্যবহার করা আরও কার্যকর তবে আপনি যে পদ্ধতিটি উল্লেখ করেছেন তা কাজ করে।
cmevoli

41
এটি কাজ sed -i 's/str1/str2/g'করার sed -i "" 's/str1/str2/g'জন্য আপনাকে ওএস এক্সে পরিবর্তন করতে হবে ।
jdf

6
এই পদ্ধতিটি সহ @cmevoli, grepসমস্ত ফাইলের মধ্য দিয়ে যায় এবং sedকেবল মিলে যাওয়া ফাইলগুলি স্ক্যান করে grep। সঙ্গে findঅন্যান্য উত্তরে পদ্ধতি, findপ্রথম তালিকা সব ফাইল, এবং তারপর sedযে ডিরেক্টরির মধ্যে সব ফাইল মাধ্যমে স্ক্যান করবে। তাই এই পদ্ধতি অগত্যা মন্থর নয়, এটা আর কত ম্যাচ আছে উপর নির্ভর করে এর মধ্যে অনুসন্ধান গতি পার্থক্য sed, grepএবং find
joelostblom

4
এই পদ্ধতিতে আপনাকে গ্রেপ প্রকৃতপক্ষে প্রতিস্থাপনের আগে কীভাবে ব্যর্থতার ঝুঁকি হ্রাস করে, বিশেষত আমার মতো রেজেক্স এন 00 বিএস-এর জন্য কী পাওয়া যায় তা প্রাকদর্শন করতে দেয়
লেনার্ট রোল্যান্ড

2
যখন আপনার গ্রেপ প্রতিস্থাপন সেডের চেয়ে বেশি চালাক হয় তখন এটিও কার্যকর। উদাহরণস্বরূপ রিপগ্রেপ মান্য করে। Gitignore করার সময় সেড দেয় না।
ব্যবহারকারী31389

43

আপনি এটি এমনকি এটি করতে পারে:

উদাহরণ

grep -rl 'windows' ./ | xargs sed -i 's/windows/linux/g'

এটি বর্তমান ডিরেক্টরি সম্পর্কিত সমস্ত ফাইলের স্ট্রিং ' উইন্ডোজ ' অনুসন্ধান করবে এবং প্রতিটি ফাইলের স্ট্রিংয়ের প্রতিটি ঘটনার জন্য ' উইন্ডোজ ' কে ' লিনাক্স ' দিয়ে প্রতিস্থাপন করবে।


2
এটি কেবল grepতখনই কার্যকর যখন ফাইলগুলি সংশোধন করা উচিত নয়। sedসমস্ত ফাইল চালানো ফাইলের পরিবর্তনের তারিখ আপডেট করবে তবে কোনও মিল না থাকলে বিষয়বস্তু অপরিবর্তিত থাকবে।
ট্রিপলি

@tripleee: থেকে সতর্ক থাকুন ... কিন্তু [sed] সামগ্রীগুলির অপরিবর্তিত রাখতে যদি সেখানে কোনো মিল নেই " যখন ব্যবহার করে। -iআমি বিশ্বাস করি sedপরিবর্তন প্রতিটি ফাইল এটা স্পর্শ ফাইল সময়, যদিও বিষয়বস্তু অপরিবর্তিত আছে। sedএছাড়াও লাইন শেষা w শ পরিবর্তন করে । আমি ব্যবহার করি না sedএকটি গীত রেপো তে Windows এ কারণ সব CRLFপরিবর্তিত হয় LF
jww

অন্তত ম্যাকোক্সে অন্তত স্থান প্রতিস্থাপনের পরে কোনও ব্যাকআপ ফাইল তৈরি হবে না তা বোঝাতে এই কমান্ডটির -i এর পরে "" প্রয়োজন। বিশদ জন্য ম্যান পৃষ্ঠা দেখুন। আপনি যদি ব্যাকআপ চান তবে এটি তৈরি করার জন্য আপনি এখানে ফাইলটির এক্সটেনশন রেখেছিলেন।
স্পাইনবাবলার

31

এটি ওএস এক্সে আমার পক্ষে সবচেয়ে ভাল কাজ করে:

grep -r -l 'searchtext' . | sort | uniq | xargs perl -e "s/matchtext/replacetext/" -pi

সূত্র: http://www.praj.com.au/post/23691181208/grep-replace-text-string-in-files


এই নিখুঁত! ag "search" -l -r . | sort | uniq | xargs perl -e 's/search/replace' -pi

@ সেবাস্তিয়ানেল্লার আপনার পার্ল কমান্ডে চূড়ান্ত স্ল্যাশের অভাব রয়েছে যা একটি সিনট্যাক্স ত্রুটি।
ট্রিপলি

3
কেন এর sort -uঅংশ এমনকি? কোন পরিস্থিতিতে আপনি grep -rlএকই ফাইলের নাম দু'বার উত্পাদন করবেন বলে আশা করবেন?
ট্রিপলি

5

অন্যান্য সমাধানগুলিতে মিশ্রিত করুন রেগেক্স সিনট্যাক্স। অনুসন্ধান এবং প্রতিস্থাপন উভয়ের জন্য পার্ল / পিসিআরই নিদর্শনগুলি ব্যবহার করতে এবং কেবলমাত্র ফাইলগুলির সাথে মিলে যাওয়া প্রক্রিয়া করার জন্য, এটি বেশ ভালভাবে কাজ করে:

grep -rlZPi 'match1' | xargs -0r perl -pi -e 's/match2/replace/gi;'

যেখানে match1এবং match2সাধারণত অভিন্ন হয় তবে match1আরও উন্নত বৈশিষ্ট্যগুলি সরানো যেতে পারে যা কেবলমাত্র প্রতিস্থাপনের সাথে প্রাসঙ্গিক, যেমন গ্রুপগুলি ক্যাপচার করে।

অনুবাদ: grepপুনরাবৃত্তভাবে এবং ফাইলগুলির নামের সাথে কোনও বিশেষ অক্ষর রক্ষার জন্য নুল দ্বারা পৃথক করা এই পিসিআরআই প্যাটার্নের সাথে মেলে এমন ফাইলগুলির তালিকা তৈরি করুন, তারপরে সেই ফাইল নামগুলিতে পাইপ করুন xargsযাতে নুল-বিচ্ছিন্ন তালিকার প্রত্যাশা রয়েছে, তবে কোনও নাম না পেলে কিছুই করবেন না, এবং perlযেখানে ম্যাচগুলি পাওয়া যায় সেখানে বিকল্প লাইনগুলিতে যান।

বাইনারি ফাইলগুলি উপেক্ষা করতে Iস্যুইচটি যুক্ত করুন grep। কেস সংবেদনশীল মেলানোর জন্য, ড্রপ iথেকে সুইচ grepএবং iপতাকা প্রতিকল্পন অভিব্যক্তি সংযুক্ত, কিন্তু নাi সুইচ উপর perlনিজেই।


পার্ল নিজেই একটি ফাইল স্ট্রাকচার পুনরাবৃত্তি করতে বেশ সক্ষম। প্রকৃতপক্ষে, এমন একটি সরঞ্জাম রয়েছে find2perlযা পার্লের সাথে জাহাজ দেয় যা কোনও xargsধোঁকা ছাড়াই এই ধরণের জিনিসটি করে ।
ট্রিপলি

@ ট্রিপলি findফাইলের সামগ্রীগুলি অনুসন্ধান করে না এবং পয়েন্টটি কেবল পার্ল প্রোগ্রামটি না লিখে ফাইলগুলি মিলে প্রক্রিয়া করা।
ওয়ালফ

এটি উইন্ডোজের জন্য একটি দুর্দান্ত সমাধান, কারণ এটি লাইন এন্ডিংগুলিকে রূপান্তরিত করার সিড-ভিত্তিক সমাধানগুলি 'এড়ানো'। ধন্যবাদ!
জামহ্যান্ডি

4

সাধারণত গ্রেপ দিয়ে নয়, বরং sed -i 's/string_to_find/another_string/g'বা এর সাথে perl -i.bak -pe 's/string_to_find/another_string/g'


3

গিট রেপো ব্যবহার করার সময় findএবং খুব সতর্ক থাকুন sed! আপনি যদি বাইনারি ফাইলগুলি বাদ না দেন তবে আপনি এই ত্রুটিটি দিয়ে শেষ করতে পারেন:

error: bad index file sha1 signature 
fatal: index file corrupt

এই ত্রুটিটি সমাধান করার জন্য sedআপনার new_stringসাথে প্রতিস্থাপন করে আপনার এটির সাথে ফিরিয়ে নেওয়া দরকার old_string। এটি আপনার প্রতিস্থাপিত স্ট্রিংগুলিকে ফিরিয়ে দেবে, সুতরাং আপনি সমস্যার শুরুতে ফিরে আসবেন।

একটি স্ট্রিং অনুসন্ধান এবং এটি প্রতিস্থাপনের সঠিক উপায় বাইনারি ফাইলগুলি উপেক্ষা করার জন্য এড়িয়ে যাওয়া findএবং তার grepপরিবর্তে ব্যবহার করা:

sed -ri -e "s/old_string/new_string/g" $(grep -Elr --binary-files=without-match "old_string" "/files_dir")

@ হবসের জন্য ক্রেডিট


1

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

find /path/to/dir -type f -iname "*filename*" -print0 | xargs -0 sed -i '/searchstring/s/old/new/g'

এই ধারণকারী সব ফাইল সন্ধান করবে filenameঅধীনে ফাইলের নামে /path/to/dirপাওয়া যে ফাইলের জন্য পরিবর্তে, সঙ্গে সঙ্গতিপূর্ণ অনুসন্ধান searchstringএবং প্রতিস্থাপন oldসঙ্গে new

যদিও আপনি যদি ফাইলের নামটিতে filenameস্ট্রিং সহ একটি নির্দিষ্ট ফাইল সন্ধান করতে বাদ দিতে চান তবে কেবল:

find /path/to/dir -type f -print0 | xargs -0 sed -i '/searchstring/s/old/new/g'

এটি উপরের একই জিনিসটি করবে তবে এর নীচে পাওয়া সমস্ত ফাইলের জন্য /path/to/dir


0

আরেকটি বিকল্প হ'ল গ্লোবস্টারের সাথে পার্ল ব্যবহার করা।

shopt -s globstarআপনার .bashrc(বা যেখানেই) সক্রিয় করা **গ্লোব প্যাটার্নটিকে সমস্ত উপ-ডিরেক্টরি এবং ফাইলকে পুনরাবৃত্তির সাথে মেলাতে দেয় ।

এভাবে ব্যবহার perl -pXe 's/SEARCH/REPLACE/g' -i **যাও recursively প্রতিস্থাপন করবে SEARCHসঙ্গে REPLACE

-Xফ্ল্যাগ "সব সতর্কবার্তা অক্ষম" থেকে Perl বলে - যার মানে এটা ডিরেক্টরি সম্পর্কে অভিযোগ করা হবে না।

Globstar এছাড়াও আপনি মত কাজগুলি করতে পারবেন sed -i 's/SEARCH/REPLACE/g' **/*.extযদি আপনি প্রতিস্থাপন করতে চেয়েছিলেন SEARCHসঙ্গে REPLACEএক্সটেনশন সঙ্গে সব সন্তানের ফাইলের মধ্যে .ext


"আরেকটি বিকল্প হ'ল গ্লোবস্টারের সাথে পার্ল ব্যবহার করা ..." - সোলারিসের মতো প্যাসিক্সি মেশিনে নয়। এজন্য আমি বিশেষভাবে খুঁজছি grepএবং sed
jtw
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.