কীভাবে বার্তাবহ বা এসডের সাথে একটি স্ট্রিংয়ের পুনরাবৃত্তির সন্ধান / প্রতিস্থাপন করবেন?


674

আমি কীভাবে প্রতিটি ঘটনাকে খুঁজে পেতে এবং প্রতিস্থাপন করব:

subdomainA.example.com

সঙ্গে

subdomainB.example.com

/home/www/ডিরেক্টরি গাছের অধীনে প্রতিটি পাঠ্য ফাইলটিতে পুনরাবৃত্তভাবে?


93
টিপ: নীচে একটি এসএনএন চেকআউট ট্রিতে করবেন না ... এটি যাদু .svn ফোল্ডার ফাইলগুলিকে ওভাররাইট করবে।
জে পোল্ফার

7
ওহ আমার thisশ্বর এই ঠিক ঠিক আমি করেছি। তবে এটি কাজ করেছে এবং মনে হয় কোনও ক্ষতি করেছে। সবচেয়ে খারাপ যে ঘটতে পারে?
জে। কাটজভিনেল

5
@ জে.ক্যাটজুইনকেল: খুব কমপক্ষে, এটি চেকসামগুলিকে দূষিত করতে পারে, যা আপনার ভান্ডারগুলিকে দূষিত করতে পারে।
নিনজেকেকো

3
শেড ব্যবহার করে সমস্ত লোকের জন্য দ্রুত পরামর্শ: এটি আপনার ফাইলে পেছনের নতুন লাইন যুক্ত করবে। আপনি যদি এগুলি না চান তবে প্রথমে এমন একটি অনুসন্ধান-প্রতিস্থাপন করুন যা কোনও কিছুর সাথে মেলে না এবং এটি গিটে প্রতিশ্রুতিবদ্ধ। তারপরে আসলটি করুন। তারপরে ইন্টারেক্টিভভাবে রিবেস করুন এবং প্রথমটি মুছুন।
ছড়িয়ে পড়ুন

5
আপনি একটি ডিরেক্টরির ব্যবহার করে ফলাফল থেকে যেমন Git যেমন অগ্রাহ্য করতে পারেন, -path ./.git -prune -ofind . -path ./.git -prune -o -type f -name '*matchThisText*' -print0xargs করার বংশীধ্বনিতুল্য আগে
devinbost

উত্তর:


850
find /home/www \( -type d -name .git -prune \) -o -type f -print0 | xargs -0 sed -i 's/subdomainA\.example\.com/subdomainB.example.com/g'

-print0findনতুন ফলাফলের পরিবর্তে নাল অক্ষর দ্বারা পৃথক করা প্রতিটি ফলাফল মুদ্রণ করতে বলে । আপনার ডিরেক্টরিতে নামগুলিতে নতুন লাইনের সাথে ফাইল রয়েছে এমন সম্ভাব্য ইভেন্টে এটি এখনও xargsসঠিক ফাইলের নামগুলিতে কাজ করতে দেয় ।

\( -type d -name .git -prune \)একটি এক্সপ্রেশন যা পুরোপুরি নামের সমস্ত ডিরেক্টরি থেকে বাদ যায় .git। আপনি সহজেই এটি প্রসারিত করতে পারেন, যদি আপনি এসভিএন ব্যবহার করেন বা অন্য ফোল্ডারগুলি সংরক্ষণ করতে চান - কেবল আরও নামের সাথে মেলে। এটি মোটামুটি সমান -not -path .git, তবে আরও দক্ষ, কারণ ডিরেক্টরিতে প্রতিটি ফাইল চেক করার পরিবর্তে এটি পুরোপুরি এড়িয়ে যায়। এর -oপরে এটি প্রয়োজনীয় কারণ -pruneআসলে কীভাবে কাজ করে।

আরও তথ্যের জন্য, দেখুন man find


132
ওএসএক্স-এ আপনি sed: 1: "...": invalid command code .সমস্যার মুখোমুখি হতে পারেন। দেখে মনে হচ্ছে যে -i বিকল্পটি এক্সটেনশন এবং পার্স 's/../...'কমান্ড আউট আশা করে। সমাধান: পাস করুন এক্সটেনশন '' থেকে -i বিকল্প sed -i '' 's/...
রবার্ট লুজো

6
দ্রষ্টব্য: আপনি যদি এটি কোনও ডিরেক্টরিতে ব্যবহার করেন এবং অবাক হন কেন svn stকোনও পরিবর্তন দেখা যায় না, কারণ আপনি .svn ডিরেক্টরিতে ফাইলগুলিও পরিবর্তন করেছেন! find . -maxdepth 1 -type f -print0 | xargs -0 sed -i 's/toreplace/replaced/g'পরিবর্তে ব্যবহার করুন।
ACK_stoverflow

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

13
grep -r 'hello' -l --null . | xargs -0 sed -i 's#hello#world#g'সম্পর্কযুক্ত ফাইল সম্পাদনা এড়ানোর জন্য এটি ব্যবহার করুন (কারণ ফাইলের এনকোডিং পরিবর্তন হতে পারে)।
ক্যাগুয়ানাহাও

6
"তবে পরিবর্তে আমার গিট সূচককে দূষিত করেছে।" এ সম্পর্কে খুব বেশি চিন্তা করবেন না আপনি কেবল find .git ... | ... 'sed -i s/(the opposite from before)/g'নিজের গিট সূচি ঠিক করতে করতে পারেন
ম্যাসেই 101

259

দ্রষ্টব্য : গিট রেপো সহ কোনও ফোল্ডারে এই কমান্ডটি চালাবেন না - .git এ পরিবর্তনগুলি আপনার গিট সূচককে দূষিত করতে পারে।

find /home/www/ -type f -exec \
    sed -i 's/subdomainA\.example\.com/subdomainB.example.com/g' {} +

এখানে অন্যান্য উত্তরের তুলনায়, এটি বেশিরভাগের চেয়ে সহজ এবং পার্লের পরিবর্তে সেড ব্যবহার করে, যা মূল প্রশ্নটি জিজ্ঞাসা করেছিল।


50
মনে রাখবেন যে আপনি BSD সেড ব্যবহার করছেন (ম্যাক ওএস এক্স সহ) আপনার সেডের -iবিকল্পের জন্য একটি স্পষ্ট ফাঁকা স্ট্রিং আর্গ প্রদান করতে হবে । যেমন: sed -i '' 's/original/replacement/g'
নাথান ক্রেইক

2
@ জনজুইনক আমার ভুল, + মিস করেছেন। আশ্চর্যের বিষয় হলেও নিকিতার সমাধানটি আমার পক্ষে দ্রুত চলে।
স্যাম

6
@ অওএও: প্রসারণের প্রক্রিয়া +সংখ্যা হ্রাস করে sed। এটি আরও দক্ষ।
জন জুইনক

4
গিট রেপো সহ আমি কোনও ফোল্ডারে কীভাবে নিরাপদে এটি করতে পারি?
হাটসেপসুট

20
এটা একটা Git রেপো ধারণকারী যদি আপনি আপনার খোঁজ ফলাফল থেকে রেপো অগ্রাহ্য একটি ফোল্ডার সঞ্চালনের জন্য নিরাপদ: find . -not -path '*/\.git*' -type f ...
ডেল অ্যান্ডারসন

210

আমার পক্ষে সবচেয়ে সহজ উপায়

grep -rl oldtext . | xargs sed -i 's/oldtext/newtext/g'

1
@ আনোটোলি: কেবল একটি প্রশ্ন: আমি কীভাবে বাইনারি ফাইলগুলি (এক্সিকিউটেবল ফাইল) বাদ দিতে পারি ?
ব্যবহারকারী 2284570

3
@ ব্যবহারকারী 2284570 -Iবা গ্রেপ --binary-file=without-matchপতাকা ব্যবহার করুন ।
জাইচিন

34
এটি বিশেষত ভাল কাজ করে, যখন আপনার সাথে ডিরেক্টরিগুলি বাদ দিতে হবে .svn। উদাহরণস্বরূপ:grep -rl oldtext . --exclude-dir=.svn | xargs sed -i 's/oldtext/newtext/g'
ফায়াট

11
brew install gnu-sedএবং gsedওএসএক্স ব্যবহার করে একটি ব্যথা বিশ্ব এড়ানোর জন্য।
পি আই

1
বলছি মনোযোগ খুশি, যদি আপনার প্রকল্পের Git versioned হয়, পরিবর্তে এই ব্যবহার করুন: git grep -rl oldtext . | xargs sed -i 's/oldtext/newtext/g'। এটা চ * আপনার আপ CK থেকে এ সব সুন্দর না .gitDir
পাওলো

61

সমস্ত কৌশল প্রায় একই, তবে আমি এটি পছন্দ করি:

find <mydir> -type f -exec sed -i 's/<string1>/<string2>/g' {} +
  • find <mydir>: ডিরেক্টরি দেখুন।

  • -type f:

    ফাইল টাইপ ধরণের: নিয়মিত ফাইল

  • -exec command {} +:

    এই-এক্সেক অ্যাকশনের এই রূপটি নির্বাচিত ফাইলগুলিতে নির্দিষ্ট কমান্ডটি চালায়, তবে প্রতিটি নির্বাচিত ফাইলের নাম শেষে অন্তর্ভুক্ত করে কমান্ড লাইনটি নির্মিত হয়; কমান্ডের অনুরোধের মোট সংখ্যা মিলিত ফাইলগুলির সংখ্যার তুলনায় অনেক কম হবে। কমান্ড লাইনটি একইভাবে নির্মিত হয়েছে যেমন xargs তার কমান্ড লাইনগুলি তৈরি করে। কমান্ডের মধ্যে কেবলমাত্র `{} 'এর একটি উদাহরণ অনুমোদিত। কমান্ডটি শুরু ডিরেক্টরিতে কার্যকর করা হয়।


@ ব্যবহারকারী 2284570--এক্সেক সহ? একটি সরঞ্জাম নামের পরিবর্তে এক্সিকিউটেবলের পথে সেট করার চেষ্টা করুন।
I159

@ আই 159: না: এক্সিকিউটেবল বাইনারিগুলি বাদ দিন (তবে শেল স্ক্রিপ্টগুলি অন্তর্ভুক্ত করুন)
ব্যবহারকারী 2284570


1
@ user2284570 একটি "বাইনারি ফাইল" ধারণাটি সম্পূর্ণরূপে সংজ্ঞায়িত নয়। fileপ্রতিটি ফাইলের ধরণ নির্ধারণের জন্য আপনি কমান্ডটি ব্যবহার করতে পারেন , তবে এর আউটপুটে হ্যাফজার্ডের বৈচিত্রগুলি কিছুটা বিচলিত হতে পারে। -I(ওরফে --mime) বিকল্প কিছুটা সাহায্য করে, বা --mime-typeআপনি যে আছে যদি। এটি করার জন্য এই ঝরঝরে ওয়ান-লাইনারটিকে ঠিক কীভাবে রিফ্যাক্টর করা যায় তা এই ক্ষুদ্র মন্তব্য বাক্সটির জন্য আক্ষেপের সুযোগ নেই scope আপনার যদি সাহায্যের প্রয়োজন হয় তবে একটি পৃথক প্রশ্ন পোস্ট করুন? (তারপরে এখানে একটি লিঙ্কের সাথে একটি মন্তব্য যুক্ত করুন))
ট্রিপলি

1
সবচেয়ে পরিষ্কার উত্তর!
সাথীদের

39
cd /home/www && find . -type f -print0 |
  xargs -0 perl -i.bak -pe 's/subdomainA\.example\.com/subdomainB.example.com/g'

2
আমি জানতে আগ্রহী নই, সেখানে ব্যবহার করার জন্য একটি কারণ নেই -print0এবং xargsপরিবর্তে -execবা -execdir?
ফিলিপ

4
এখানে "ম্যান ফাইন্ড" থেকে রয়েছে: প্রতিটি ম্যাচ করা ফাইলের জন্য নির্দিষ্ট কমান্ডটি একবার চালানো হয়। এটি হ'ল যদি / home / www এ 2000 টি ফাইল থাকে তবে 'সন্ধান করুন ...-এক্সেক ...' এর ফলে 2000 পার্লের অনুরোধ হবে; যেখানে 'খুঁজে ... | xargs ... 'কেবল একবার বা দু'বার পার্লের জন্য আহ্বান জানাবে (প্রায় 32K এর ARG_MAX এবং 20 এর গড় ফাইলের নাম দৈর্ঘ্য ধরে)।
রাশিয়ান নিয়োগ

2
@ কর্মরত রাশিয়ান: এজন্য আপনি ব্যবহার করতে চান find -exec command {} +- এটি xargs এর মতো কমান্ডের অতিরিক্ত আহবান এড়াতে পারে না, তবে পৃথক প্রক্রিয়া ছাড়াই।
জন জুইঙ্ক

2
কোন প্লাটফর্মে? এক্সআরগস সমাধানটি পোর্টেবল, "সন্ধান ... -এক্সেক" এর "যাদু" অনুরোধগুলি যা পাওয়া প্রতিটি ফাইলের জন্য একটি সাবপ্রসেসের অনুরোধ করে না।
রাশিয়াকে

4
@ কর্মরত রুশিয়ান ২০০ find -exec ... {} +2006 সাল থেকে পসিক্স -নির্দিষ্ট করা হয়েছে।
চার্লস ডাফি

34

আমার কাছে মনে রাখার সবচেয়ে সহজ সমাধানটি হল https://stackoverflow.com/a/2113224/565525 , অর্থাত:

sed -i '' -e 's/subdomainA/subdomainB/g' $(find /home/www/ -type f)

দ্রষ্টব্য : -i ''ওএসএক্স সমস্যা সমাধান করেsed: 1: "...": invalid command code .

দ্রষ্টব্য : প্রসেস করার জন্য খুব বেশি ফাইল থাকলে আপনি পাবেন Argument list too long। কার্যবিবরণী - উপরে বর্ণিত ব্যবহার find -execবা xargsসমাধান।


4
workaroundসব ক্ষেত্রেই পছন্দের সিনট্যাক্স হওয়া উচিত।
মনিকা পুনরায় ইনস্টল করুন

1
কমান্ড প্রতিস্থাপনের সমস্যাটি $(find...)হ'ল শেলটির মধ্যে শ্বেত স্পেস বা অন্যান্য শেল মেটাচার্যাক্টরগুলির সাথে ফাইলের নাম হ্যান্ডেল করার কোনও উপায় নেই। যদি আপনি জানেন যে এটি কোনও সমস্যা নয় তবে এই পদ্ধতিটি ঠিক আছে; তবে আমাদের কাছে এমন অনেক প্রশ্ন রয়েছে যেখানে লোকেরা এই বিষয় সম্পর্কে সতর্ক হননি বা সতর্কতাটি বুঝতে পারেন নি।
ট্রিপলি

30

রৌপ্য অনুসন্ধানকারী যে কেউ ব্যবহার করে ( ag)

ag SearchString -l0 | xargs -0 sed -i 's/SearchString/Replacement/g'

যেহেতু এজি ডিফল্টরূপে গিট / এইচজি / এসএনএন ফাইল / ফোল্ডারগুলি উপেক্ষা করে, তাই এটি কোনও সংগ্রহস্থলের অভ্যন্তরে চালানো নিরাপদ।


16

অতিরিক্ত হিসাবে একটি সুন্দর অনেলাইনার। গিট গ্রেপ ব্যবহার

git grep -lz 'subdomainA.example.com' | xargs -0 perl -i'' -pE "s/subdomainA.example.com/subdomainB.example.com/g"

3
গিট রেপোতে কাজ করার ক্ষেত্রে ভাল ধারণা যদি আপনি ওভার রাইটিং ঝুঁকি না করেন তবে .git / বিষয়বস্তু (অন্য উত্তরের মন্তব্যে উল্লিখিত হিসাবে)।
মাহেমফ 21

1
ধন্যবাদ, আমি এটি ব্যাশ ফাংশন refactor() { echo "Replacing $1 by $2 in all files in this git repository." git grep -lz $1| xargs -0 perl -i'' -pE "s/$1/$2/g" }ব্যবহার হিসাবে ব্যবহার করি , উদাহরণস্বরূপ 'তরোয়াল' দিয়ে 'শব্দ' প্রতিস্থাপন করতে: refactor word swordতারপরে এটি কী হয়েছে তা যাচাই করুন git diff
পল রাউজিউক্স

16

পুনরাবৃত্তির sedমাধ্যমে ফাইলগুলি কেটে ফেলার grepজন্য , আপনি আপনার স্ট্রিং উদাহরণটির জন্য এটি করতে পারেন :

grep -rl <oldstring> /path/to/folder | xargs sed -i s^<oldstring>^<newstring>^g

আপনি যদি চালনা করেন তবে man grepলক্ষ্য করবেন যে আপনি একটি সংজ্ঞাও দিতে পারেন--exlude-dir="*.git" যে আপনি .git ডিরেক্টরিতে অনুসন্ধান বাদ দিতে চাইলে গিট ইনডেক্সের বিষয়গুলি এড়ানো যেমন অন্যরা বিনয়ের সাথে নির্দেশ করেছেন তাই আপনি পতাকাও ।

আপনাকে এখানে নিয়ে যাওয়া:

grep -rl --exclude-dir="*.git" <oldstring> /path/to/folder | xargs sed -i s^<oldstring>^<newstring>^g

13

এইটি গিট সংগ্রহস্থলের সাথে সামঞ্জস্যপূর্ণ এবং কিছুটা সহজ:

লিনাক্স:

git grep -l 'original_text' | xargs sed -i 's/original_text/new_text/g'

ম্যাক:

git grep -l 'original_text' | xargs sed -i '' -e 's/original_text/new_text/g'

(ধন্যবাদ http://blog.jasonmeridth.com/posts/use-git-grep-to-replace-strings-in-files-in-your-git-repository/ )


উইজার git-grepএর -zবিকল্পগুলি একসাথে ব্যবহার করতে xargs -0
gniourf_gniourf

git grepস্পষ্টতই কেবল একটি gitরেপোতে বোঝা যায় । সাধারণ প্রতিস্থাপন হবে grep -r
ট্রিপলি

@gniourf_gniourf আপনি কি ব্যাখ্যা করতে পারেন?
পেট্র পেলার 24'17

2
@PetrPeller সাথে -z, git-grepআউটপুট ক্ষেত্র নাল দ্বারা নতুন লাইন পরিবর্তে বাইট আলাদা হবে; এবং -0, xargsপড়তে হবে ইনপুট ঐ খালি পরিবর্তে, নাল বাইট দ্বারা পৃথক (এবং কোট দিয়ে অদ্ভুত জিনিস না)। তাই আপনি যদি বিরতি কমান্ড না চান তাহলে ফাইলের নামের স্পেস, কোট বা অন্যান্য মজার অক্ষর, কমান্ড: git grep -z -l 'original_text' | xargs -0 sed ...
gniourf_gniourf

10
find /home/www/ -type f -exec perl -i.bak -pe 's/subdomainA\.example\.com/subdomainB.example.com/g' {} +

find /home/www/ -type f / home / www / (এবং এর উপ-ডিরেক্টরি) সমস্ত ফাইল তালিকাভুক্ত করবে। "-Exec" পতাকাটি পাওয়া প্রতিটি ফাইলের জন্য নিম্নলিখিত কমান্ডটি চালনা করতে বলে।

perl -i.bak -pe 's/subdomainA\.example\.com/subdomainB.example.com/g' {} +

ফাইলগুলিতে চালিত কমান্ডটি (একসাথে অনেকগুলি)। {}ফাইলের নাম দ্বারা প্রতিস্থাপিত হয়। +কমান্ডের শেষে বলেfind অনেক ফাইলের নামের জন্য এক কমান্ড গড়ে তুলতে।

findম্যান পেজটির জন্য : "কমান্ড লাইনটি ঠিক একইভাবে নির্মিত যেমন xargs তার কমান্ড লাইনগুলি তৈরি করে।"

সুতরাং xargs -0, বা ব্যবহার না করেই আপনার লক্ষ্য অর্জন (এবং স্পেসযুক্ত ফাইলের নামগুলি হ্যান্ডেল করা) অর্জন সম্ভব -print0


8

আমার কেবল এটির প্রয়োজন ছিল এবং উপলব্ধ উদাহরণগুলির গতিতে সন্তুষ্ট ছিল না। তাই আমি আমার নিজের সাথে এসেছি:

cd /var/www && ack-grep -l --print0 subdomainA.example.com | xargs -0 perl -i.bak -pe 's/subdomainA\.example\.com/subdomainB.example.com/g'

অ্যাক-গ্রেপ প্রাসঙ্গিক ফাইলগুলি সন্ধানের জন্য খুব দক্ষ। এই কমান্ডটি একটি বাতাসের সাথে ~ 145 000 ফাইলগুলি প্রতিস্থাপন করেছে অন্যরা এত দীর্ঘ সময় নিয়েছিল আমি শেষ না হওয়া পর্যন্ত অপেক্ষা করতে পারিনি।


দুর্দান্ত, তবে grep -ril 'subdomainA' *যত দ্রুতগতির কাছাকাছি কোথাও নেই grep -Hr 'subdomainA' * | cut -d: -f1
trusktr

@ হেন্নো: কেবল একটি প্রশ্ন: আমি কীভাবে বাইনারি ফাইলগুলি (এক্সিকিউটেবল ফাইল) বাদ দিতে পারি ?
ব্যবহারকারী 2284570

ack-grep এটি আপনার জন্য স্বয়ংক্রিয়ভাবে করে।
হেনো

@ হেন্নো: এতে কি শেল লিপি অন্তর্ভুক্ত রয়েছে?
ব্যবহারকারী 2284570

হ্যাঁ. এটি সমর্থিত ফাইল ধরণের একটি সম্পূর্ণ তালিকা এখানে রয়েছে: পরাশক্তি
হেনো

6

সরাসরি ডিরেক্টরি পদ্ধতি যদি আপনাকে ডিরেক্টরিগুলি বাদ দিতে হয় ( --exclude-dir=.svn) এবং ফাঁকা জায়গাগুলির সাথে ফাইলের নামও থাকতে পারে ( grep -Zএবং সাথে 0 বাইট ব্যবহার করে এবংxargs -0

grep -rlZ oldtext . --exclude-dir=.svn | xargs -0 sed -i 's/oldtext/newtext/g'

6

প্রতিস্থাপনের সহজ উপায় ( সমস্ত ফাইল, ডিরেক্টরি, পুনরাবৃত্ত )

find . -type f -not -path '*/\.*' -exec sed -i 's/foo/bar/g' {} +

দ্রষ্টব্য: কখনও কখনও আপনার কিছু লুকানো ফাইলগুলি উপেক্ষা করার প্রয়োজন হতে পারে.git , আপনি উপরের কমান্ডটি ব্যবহার করতে পারেন।

আপনি যদি লুকানো ফাইল ব্যবহার অন্তর্ভুক্ত করতে চান,

find . -type f  -exec sed -i 's/foo/bar/g' {} +

উভয় ক্ষেত্রেই স্ট্রিংটি fooনতুন স্ট্রিংয়ের সাথে প্রতিস্থাপন করা হবেbar


5

grep -lr 'subdomainA.example.com' | while read file; do sed -i "s/subdomainA.example.com/subdomainB.example.com/g" "$file"; done

আমি অনুমান করি যে বেশিরভাগ লোকেরা জানেন না যে তারা "ফাইল পড়ার সময়" তে কোনও কিছু পাইপ করতে পারেন এবং এটি ফাইলের নামগুলিতে ফাঁকা স্থান প্রেরণ করার সময়, এইগুলি বাজে-প্রিন্ট 0 টি আর্গগুলি এড়িয়ে যায়।

আরও কিছু যোগ করার echoআগে সেড আপনাকে দেখতে দেবে যে আসলে ফাইলগুলি করার আগে কোন ফাইলগুলি পরিবর্তন হবে।


কারণটি -print0দরকারী এটি হ'ল কেসগুলি while readহ্যান্ডেল করে যা কেবল হ্যান্ডেল করতে পারে না - একটি নিউলাইন হ'ল ইউনিক্স ফাইলের নামের একটি বৈধ অক্ষর, সুতরাং আপনার কোডটি পুরোপুরি মজবুত হওয়ার জন্য, এ জাতীয় ফাইলের নামগুলিও সামলাতে হবে। (এছাড়াও, আপনি read -rকিছু বেঁচে থাকা read
পসিক্স

এছাড়াও, sedযদি কোনও মিল নেই তবে এটি কোনও অপশন নয়, সুতরাং এটি grepসত্যই প্রয়োজনীয় নয়; যদিও আপনার কাছে প্রচুর মিল রয়েছে বা অকারণে ফাইলগুলিতে তারিখের স্ট্যাম্পগুলি আপডেট করা থেকে বিরত থাকতে চাইলে কোনও মিল নেই এমন ফাইলগুলি পুনরায় লেখার বিষয়টি এড়িয়ে যাওয়ার জন্য এটি একটি দরকারী অপ্টিমাইজেশন।
ট্রিপলি

5

এটি নীচের মত সমাধানের জন্য আপনি awk ব্যবহার করতে পারেন,

for file in `find /home/www -type f`
do
   awk '{gsub(/subdomainA.example.com/,"subdomainB.example.com"); print $0;}' $file > ./tempFile && mv ./tempFile $file;
done

আশা করি এটা তোমাকে সাহায্য করবে !!!


ম্যাকওগুলিতে কোনও সমস্যা ছাড়াই কাজ করে! সমস্ত sedভিত্তিক কমান্ড ব্যর্থ হয় যখন বাইনারি এমনকি অসক্স নির্দিষ্ট সেটিংস সহ অন্তর্ভুক্ত করা হয়।
জাঙ্কাপঙ্ক্ট

সাবধানতা ... ফাইলগুলির findরিটার্নগুলির কোনওটির কাছে যদি জায়গা থাকে তবে এটি ফুরিয়ে যাবে! এটি ব্যবহার করা অনেক বেশি নিরাপদ while read: stackoverflow.com/a/9612560/1938956
সোরেন বজর্নস্টাড

4

এটা চেষ্টা কর:

sed -i 's/subdomainA/subdomainB/g' `grep -ril 'subdomainA' *`

1
হাই @ রিকহিক, দুর্দান্ত টিপ - এরকম কিছু সম্পর্কে ভাবছিলাম; দুর্ভাগ্যক্রমে উপরের ফর্ম্যাটটি পুরোপুরি ডানদিকে পরিণত হয়নি :) সুতরাং আমি প্রাক ট্যাগ দিয়ে চেষ্টা করব (কাজ করে না) - তখন ব্যাকটিক্স পলায়নের সাথে: sed -i 's/subdomainA/subdomainB/g'` grep -ril 'subdomainA' /home/www/*` - এটি এখনও খুব ভাল দেখাচ্ছে না, তবে উচিত কোপাইপস্টে বেঁচে থাকুন :) চিয়ার্স!
sdaau

4
#!/usr/local/bin/bash -x

find * /home/www -type f | while read files
do

sedtest=$(sed -n '/^/,/$/p' "${files}" | sed -n '/subdomainA/p')

    if [ "${sedtest}" ]
    then
    sed s'/subdomainA/subdomainB/'g "${files}" > "${files}".tmp
    mv "${files}".tmp "${files}"
    fi

done

4

মতে এই ব্লগ পোস্টে:

find . -type f | xargs perl -pi -e 's/oldtext/newtext/g;'

তুমি কীভাবে ছিটকে পড়বে /? উদাহরণস্বরূপ, আমি আইপি ঠিকানাগুলি প্রতিস্থাপন করতে চাই: এর xxx.xxx.xxx.xxxজন্যxxx.xxx.xxx.xxx/folder
প্যাথ্রোস

আপনি /with দিয়ে পালাতে পারবেন উদাহরণস্বরূপ:find . -type f | xargs perl -pi -e 's/xxx.xxx.xxx.xxx\/folder/newtext/g;'
J.Hpour

3

আপনি যদি vimএকসাথে grepবা findসরঞ্জামগুলি ব্যবহার করে কিছু মনে করেন না , তবে আপনি এই লিঙ্কটিতে ব্যবহারকারী জার্টের দেওয়া উত্তরটি অনুসরণ করতে পারেন -> একটি বড় ফোল্ডার স্তরক্রমের ক্ষেত্রে কোনও পাঠ্য প্রতিস্থাপন কীভাবে করবেন?

চুক্তিটি এখানে:

  • আপনি একটি নির্দিষ্ট পথে প্রতিস্থাপন করতে চান সেই স্ট্রিংটির জন্য পুনরাবৃত্তভাবে গ্রেপ করুন, এবং কেবলমাত্র ম্যাচের ফাইলটির সম্পূর্ণ পথ নিন। (এটি হবে $(grep 'string' 'pathname' -Rl)

  • (alচ্ছিক) আপনি যদি সেন্ট্রালাইজড ডিরেক্টরিতে এই ফাইলগুলির প্রাক-ব্যাকআপ করতে চান তবে আপনি এটিও ব্যবহার করতে পারেন: cp -iv $(grep 'string' 'pathname' -Rl) 'centralized-directory-pathname'

  • এর পরে আপনি vimপ্রদত্ত লিঙ্কে প্রদত্ত অনুরূপ একটি স্কিম অনুসরণ করে ইচ্ছামত সম্পাদনা / প্রতিস্থাপন করতে পারবেন :

    • :bufdo %s#string#replacement#gc | update

2

কিছুটা পুরানো স্কুল তবে এটি ওএস এক্সে কাজ করেছে

কয়েকটি কৌশল আছে:

.slsCurrent কেবলমাত্র বর্তমান ডিরেক্টরিতে এক্সটেনশন সহ ফাইলগুলি সম্পাদনা করবে

"কোনও চরিত্র" হিসাবে তাদের মূল্যায়ন না করে তা .নিশ্চিত করতে অবশ্যই পালাতে হবে •sed

• স্বাভাবিকের পরিবর্তে ডিলিমিটার ,হিসাবে ব্যবহৃত হয়sed/

এছাড়াও নোট করুন এটি variableকোনও পথে পাস করার জন্য একটি জিনজা টেম্পলেট সম্পাদনা করা import(তবে এটি বিষয় ছাড়াই)।

প্রথমে আপনার এসড কমান্ডটি যা চান তা যাচাই করুন (এটি কেবল স্টাডাউটে পরিবর্তনগুলি মুদ্রণ করবে, এটি ফাইলগুলি পরিবর্তন করবে না):

for file in $(find . -name *.sls -type f); do echo -e "\n$file: "; sed 's,foo\.bar,foo/bar/\"+baz+\"/,g' $file; done

একবার আপনি পরিবর্তন করার জন্য প্রস্তুত হয়ে উঠলে প্রয়োজনীয় সেড কমান্ডটি সম্পাদনা করুন:

for file in $(find . -name *.sls -type f); do echo -e "\n$file: "; sed -i '' 's,foo\.bar,foo/bar/\"+baz+\"/,g' $file; done

সেড কমান্ডের -i ''মধ্যে নোট করুন , আমি মূল ফাইলগুলির একটি ব্যাকআপ তৈরি করতে চাইনি ( ওএস এক্সে সেডের সাথে ইন-প্লেস সম্পাদনাগুলিতে ব্যাখ্যা করা হয়েছে ) এই পাতায় বা রবার্ট Lujo এর মন্তব্যে)।

ভাবী শুভ!


2

শুধু পরিবর্তন এড়াতে

  • NearlysubdomainA.example.com
  • subdomainA.example.comp.other

কিন্তু এখনো

  • subdomainA.example.com.IsIt.good

(ডোমেন রুটের পিছনে ধারণায় সম্ভবত ভাল না)

find /home/www/ -type f -exec sed -i 's/\bsubdomainA\.example\.com\b/\1subdomainB.example.com\2/g' {} \;

2

আমি কেবল শীর্ষগুলি ব্যবহার করি:

find . -name '*.[c|cc|cp|cpp|m|mm|h]' -print0 |  xargs -0 tops -verbose  replace "verify_noerr(<b args>)" with "__Verify_noErr(<args>)" \
replace "check(<b args>)" with "__Check(<args>)" 

প্লাস `জন্য এক '* [গ | CC | CP | CPP | মি | মিমি | জ]।' '
FractalSpace

2

এখানে এমন একটি সংস্করণ রয়েছে যা বেশিরভাগের চেয়ে সাধারণ হতে হবে; উদাহরণস্বরূপ এর প্রয়োজন নেই find( duপরিবর্তে ব্যবহার করা)। এটির প্রয়োজন হয় xargsযা কেবল প্ল্যান 9 এর কিছু সংস্করণে পাওয়া যায় (যেমন 9 ফ্রন্ট)।

 du -a | awk -F' '  '{ print $2 }' | xargs sed -i -e 's/subdomainA\.example\.com/subdomainB.example.com/g'

আপনি যদি ফাইল এক্সটেনশনগুলির মতো ফিল্টারগুলি যুক্ত করতে চান তবে grep:

 du -a | grep "\.scala$" | awk -F' '  '{ print $2 }' | xargs sed -i -e 's/subdomainA\.example\.com/subdomainB.example.com/g'

1

আইবিএমিতে কিশেল (কিউএস) এর জন্য, ওপি দ্বারা ট্যাগ করা বাশ নয়।

Qsh কমান্ডের সীমাবদ্ধতা:

  • অনুসন্ধান--প্রিন্ট 0 বিকল্প নেই
  • xargs -0 বিকল্প নেই
  • সেড -i বিকল্প নেই

সুতরাং Qsh মধ্যে সমাধান:

    PATH='your/path/here'
    SEARCH=\'subdomainA.example.com\'
    REPLACE=\'subdomainB.example.com\'

    for file in $( find ${PATH} -P -type f ); do

            TEMP_FILE=${file}.${RANDOM}.temp_file

            if [ ! -e ${TEMP_FILE} ]; then
                    touch -C 819 ${TEMP_FILE}

                    sed -e 's/'$SEARCH'/'$REPLACE'/g' \
                    < ${file} > ${TEMP_FILE}

                    mv ${TEMP_FILE} ${file}
            fi
    done

আদেশ সহকারে:

  • সমাধান ত্রুটি পরিচালনা পরিচালনা বাদ দেয়
  • ওপি দ্বারা ট্যাগ হিসাবে বাশ নয়

এটিতে উদ্ধৃত করার পাশাপাশি কিছুটা লাইন পড়ার সমস্যা রয়েছে for
ট্রিপলি

1

আপনি যদি নিজের এসভিএন সংগ্রহস্থলটিকে সম্পূর্ণরূপে বিনষ্ট না করে এটি ব্যবহার করতে চান, আপনি সমস্ত ফাইল লুকিয়ে রেখে 'অনুসন্ধান' বলতে পারেন:

find . \( ! -regex '.*/\..*' \) -type f -print0 | xargs -0 sed -i 's/subdomainA.example.com/subdomainB.example.com/g'

প্রথম বন্ধনীগুলি অতিমাত্রায় উপস্থিত বলে মনে হচ্ছে। এর আগে ফর্ম্যাটিংয়ের ত্রুটি ছিল যা এটিকে অকেজো করে তোলে (মার্কডাউন রেন্ডারিং রেজেক্স থেকে কিছু অক্ষর খাবে)।
ট্রিপল

1

grepএবং এর সংমিশ্রণ ব্যবহার করেsed

for pp in $(grep -Rl looking_for_string)
do
    sed -i 's/looking_for_string/something_other/g' "${pp}"
done

@ ট্রিপলি আমি এটি কিছুটা পরিবর্তন করেছি। এই ক্ষেত্রে কমান্ডের জন্য আউটপুট grep -Rl patternফাইলের প্যাটার্নের তালিকা তৈরি করে। ফাইলগুলি forলুপে পড়ে না ।
পাভেল

তাই না? আপনার এখনও একটি forলুপ আছে; যদি কোনও ফেরত ফাইলের নামটিতে সাদা স্থান থাকে তবে এটি সঠিকভাবে কাজ করবে না, কারণ শেলটি forআর্গুমেন্টের তালিকাকে টোকানাইজ করে । তবে তারপরে আপনি লুপের ভিতরে উদ্ধৃতিবিহীন ফাইলের নাম ভেরিয়েবলটি ব্যবহার করেন, সুতরাং আপনি যদি এটি স্থির করেন তবে পরিবর্তে এটি সেখানে ভেঙে যায়। এই বাকী বাগগুলি সংশোধন করা আপনার @ ম্যাডম্যান 2064 এর উত্তরের মতো হয়ে যাবে।
ট্রিপল

@ ট্রিপলি হ্যাঁ, এটি সত্য, আমি এটি মিস করেছি।
পাভেল

1

গিট সংগ্রহস্থলের সমস্ত উপস্থিতি প্রতিস্থাপনের জন্য আপনি ব্যবহার করতে পারেন:

git ls-files -z | xargs -0 sed -i 's/subdomainA\.example\.com/subdomainB.example.com/g'

স্থানীয় গিট রেপোতে তালিকা ফাইলগুলি দেখুন ? অন্যান্য বিকল্পগুলির জন্য একটি সংগ্রহস্থলে সমস্ত ফাইল তালিকাবদ্ধ করতে। -zঅপশন Git বলে একটি শূন্য বাইট, যা আশ্বাস দেয় যে, সঙ্গে ফাইলের নাম আলাদা করা xargs(বিকল্প -0) ফাইলের নামের আলাদা করতে পারেন, এমনকি যদি তারা স্পেস বা যে কোন বস্তু ধারণ করে।


1
perl -p -i -e 's/oldthing/new_thingy/g' `grep -ril oldthing *`

1
awk/ ব্যবহার করে না sed, তবে পার্ল সাধারণ (কেবল ব্যস্তবক্স সহ এম্বেড / সিস্টেমগুলি বাদে)।
পেভিক

1

একাধিক ফাইল পরিবর্তন করতে (এবং হিসাবে একটি ব্যাকআপ সংরক্ষণ করা *.bak):

perl -p -i -e "s/\|/x/g" *

সমস্ত ফাইল ডিরেক্টরিতে নিয়ে যাবে এবং |এক্স দিয়ে প্রতিস্থাপন করবে একটি "পার্ল পাই" নামে পরিচিত (পাই হিসাবে সহজ)


যদিও ডিরেক্টরি মাধ্যমে পুনরাবৃত্তি না।
পিকেহান্টার

এটিতে পাইপ দেওয়া সম্ভব, এটি ডিরেক্টরিগুলির মাধ্যমে এটি খুব সামঞ্জস্য করে তোলে। josephscott.org/archives/2005/08/… এবং ইউনিক্স.স্ট্যাকেক্সচেঞ্জ
সেকশন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.