সঠিক লাইনটি খুঁজে পেতে গ্রেপ করবেন, বিষয়বস্তুগুলি পরিবর্তন করতে হবে, তারপরে এটিকে মূল ফাইলে রেখে দেবেন?


9

আমি একটি ফাইলের একটি নির্দিষ্ট লাইনে একটি শব্দ পরিবর্তন করার চেষ্টা করছি, তবে সমস্ত একসাথে সংযোগ করতে আমার কিছুটা সমস্যা হচ্ছে।

মূলত, আমার ফাইলে একটি লাইনে 'ফার্মওয়্যার_রিভিশন' কীওয়ার্ড রয়েছে এবং এই লাইনে (এবং কেবল এই লাইনটিতে) আমি 'পরীক্ষার' শব্দটি 'উত্পাদন' শব্দের সাথে প্রতিস্থাপন করতে চাই।

সুতরাং আমি এটি করতে পারি:

grep 'firmware_revision' myfile.py | sed 's/test/production'

এটি আমার পছন্দসই লাইনটি বেছে নেবে এবং প্রতিস্থাপনটি সম্পাদন করবে, তবে কীভাবে পুরানো রেখাটি প্রতিস্থাপনের জন্য এই নতুন লাইনটি মূল ফাইলটিতে পাবেন তা আমি বুঝতে পারি না। আমি অবশ্যই এটি পুনরায় ফাইলে পুনর্নির্দেশ করতে পারি না, তাই আমার কী করা উচিত?

এমনকি যদি আমি টেম্পোরারিগুলি ব্যবহার করি, grepকেবলমাত্র আমার প্রয়োজনীয় লাইনটি ব্যবহার করে আমি ফাইলের অন্যান্য সমস্ত ডেটা হারাতে পারি, তাই আমি আর এটিকে কেবল কোনও টেম্প ফাইলে পুনর্নির্দেশ করতে পারি না, তবে মূলটি টেম্পের সাথে প্রতিস্থাপন করতে পারি।

সম্পাদনা করুন - কেউ আরও তথ্য চেয়েছে

বলি আমার কাছে লাইনের মতো একটি ফাইল রয়েছে

[
  ('key_name1', str, 'value1', 'Description'),
  ('key_name2', str, 'value2', 'Description'),
  ('key_name3', str, 'value3', 'Description'),
  ('firmware_revision', str, 'my-firmware-name-test', 'Firmware revision name')
]

এখন আমি একটি স্ক্রিপ্ট লিখতে চাই (আদর্শভাবে একটি লাইনার) যা 'ফার্মওয়্যার_রিভিশন' সম্বলিত লাইনটি খুঁজে পেতে পারে এবং সেই পরীক্ষায় 'পরীক্ষা' শব্দের সমস্ত উদাহরণকে 'উত্পাদনে' পরিবর্তিত করে। 'পরীক্ষা' শব্দটি সেই ফাইলের অন্য জায়গায় থাকতে পারে এবং আমি সেগুলি পরিবর্তন করতে চাই না। সুতরাং পরিষ্কার হতে, আমি উপরের লাইন পরিবর্তন করতে চান

('firmware_revision', str, 'my-firmware-name-production', 'Firmware revision name')

আমি এটা কিভাবে করবো?


5
sedখুব শক্তিশালী, এটি উভয় ফাংশন ( grepএবং প্রতিস্থাপন) সম্পাদন করতে পারে তবে রেখাটি আপনাকে কীভাবে সহায়তা করতে দেখায় সে সম্পর্কে আমাদের আরও তথ্যের প্রয়োজন হবে।
গ্রোচামাল

আমি আসল পোস্টে আরও তথ্য যুক্ত করব
জন এলার্ড

7
চেষ্টা করুন:sed -i.bak '/firmware_revision/ s/test/production/' myfile.py
1024

1
আহ এটি নিখুঁতভাবে কাজ করেছে! আপনি সিনট্যাক্স ব্যাখ্যা করতে পারেন?
জন অ্যালার্ড

@ জন অ্যালার্ড খুব ভাল আমি ব্যাখ্যা সহ একটি উত্তর যুক্ত করেছি।
1024

উত্তর:


22

চেষ্টা করুন:

sed -i.bak '/firmware_revision/ s/test/production/' myfile.py

এখানে, /firmware_revision/একটি শর্ত হিসাবে কাজ করে। রেজেক্সের সাথে মেলে এমন রেখাগুলির ক্ষেত্রে এটি সত্য firmware_revisionএবং অন্য লাইনের সাথে মিথ্যা। যদি কন্ডিশনটি সত্য হয়, তবে নিম্নলিখিত কমান্ডটি কার্যকর করা হবে। এই ক্ষেত্রে, কমান্ডটি একটি বিকল্প কমান্ড যা প্রথম উপস্থিতির testসাথে প্রতিস্থাপন করে production

অন্য কথায়, কমান্ডটি s/test/production/কেবলমাত্র লাইনে কার্যকর করা হয় যা রেজেক্সের সাথে মেলে firmware_revision। অন্য সমস্ত লাইন অপরিবর্তিত হয়ে যায়।

ডিফল্টরূপে, সেড তার আউটপুটটিকে স্ট্যান্ডার্ড আউট প্রেরণ করে। আপনি তবে ফাইলটি জায়গায় বদলাতে চেয়েছিলেন। সুতরাং, আমরা -iবিকল্পটি যুক্ত করেছি। বিশেষত, -i.bakএকটি .bakএক্সটেনশান সহ সংরক্ষিত ব্যাক-আপ অনুলিপি সহ ফাইলটি জায়গায় স্থান পরিবর্তন করে ।

যদি আপনি সিদ্ধান্ত নিয়েছেন যে কমান্ডটি আপনার পক্ষে কাজ করে এবং আপনি বিপজ্জনকভাবে বাঁচতে চান এবং ব্যাকআপ তৈরি করতে চান না, তবে GNU সেড (লিনাক্স) সহ, ব্যবহার করুন:

sed -i '/firmware_revision/ s/test/production/' myfile.py

বিপরীতে, BSD (ওএসএক্স) এ, -iবিকল্পটির অবশ্যই একটি যুক্তি থাকতে হবে। আপনি যদি কোনও ব্যাকআপ রাখতে চান না, এটি একটি খালি যুক্তি সরবরাহ করুন। সুতরাং, ব্যবহার করুন:

sed -i '' '/firmware_revision/ s/test/production/' myfile.py

সম্পাদন করা

প্রশ্নের সম্পাদনায়, ওপিকে লাইনের প্রতিটি ঘটনাই testপ্রতিস্থাপনের জন্য বলেছে production। সেক্ষেত্রে আমরা গ্লোবাল (সেই লাইনের জন্য) প্রতিস্থাপনের জন্য gবিকল্প কমান্ডের বিকল্পটি যুক্ত করব :

sed -i.bak '/firmware_revision/ s/test/production/g' myfile.py

5
সম্পূর্ণতার জন্য, আপনি -i.bakপাশাপাশি অংশটি ব্যাখ্যা করতে চাইতে পারেন ।
স্টিফেন হ্যারিস

5
পুনঃটুইট যুক্ত করার ব্যাখ্যা -i
1024

আমি মনে করি আপনি সম্ভবত তারকাদের কাছে পৌঁছে দিতে পারেন, কেবল বইয়ের উপরে দাঁড়িয়ে যা sedকরতে পারে তার সমস্ত কিছুই ব্যাখ্যা করে ...
KlaymenDK

@ John1024 না বাসদ মানুষের জন্য, আপনি প্রথম কয়েকজনের কারণে যোগ করতে পারিনি ''পর -i?
হাস্তুর

3
ওপি সেই লাইনে থাকা 'টেস্ট' শব্দের সমস্ত দৃষ্টান্তকে পরিবর্তিত করে 'উত্পাদন' করতে চেয়েছিল । এই ক্ষেত্রে সেড কমান্ডে / জি সংযুক্ত করা গুরুত্বপূর্ণ: sed -i '/firmware_revision/ s/test/production/g' myfile.pyঅন্যথায় কেবল প্রথম উদাহরণটি পরিবর্তিত হয় changed
নুব

4

পুরানো-স্কুলযুক্ত পুরানো মেশিনগুলিতে যা sedবিকল্প সমর্থন করে না -i:

TF=$( mktemp -t "${0##*/}"_$$_XXXXXXXX ) && \
trap 'rm -f "$TF"' EXIT HUP INT QUIT TERM && \
sed '/firmware_revision/ s/test/production/' myfile.py >"$TF" && \
mv -f "$TF" myfile.py

1
এই পুরানো মেশিনগুলিতে আপনি কেবল edএক লাইনে এটি ব্যবহার এবং করতে পারেন:printf %s\\n g/firmware_revision/s/test/production/g w q | ed -s myfile.py
ডোন_ক্রিসটি

1
@ Don_crissti এটি খুব সত্য, তবে ed(1)এর ব্যবহার দেখানোর জন্য কোনও অজুহাত দেয় না mktemp(1)
স্যাট কাটসুরা

আপনি যদি কোনও টেম্পাইল ব্যবহার করছেন তবে আপনি মূল ফাইলটির ইনোড এবং পারমগুলি একইভাবে রাখতে edপারেন। পরিবর্তে mv -f "$TF" myfile.pl, ব্যবহার করুন cat "$TF" > myfile.pl && rm -f "$TF"। বিটিডাব্লু, লোয়ারকেস ভেরিয়েবলের নামগুলি ব্যবহারের $tfপরিবর্তে ( পরিবর্তে $TF) এটি ভাল অনুশীলন , কোনও বিল্ট-ইন ওয়ার (সম্ভবত অন্যান্য বোর্ন শেলও) এর সাথে বিরোধ না করার গ্যারান্টিযুক্ত তারা।
ক্যাস

@ ক্যাস রি:: এটি cat "$TF" > myfile.plচেষ্টা করুন: touch a b; chmod 0444 a; cat b >a( বিটিডাব্লু , sed -iসে ক্ষেত্রেও কাজ করবে না)। ব্যবহারকারী যে এটি মোকাবেলা করা ভাল। পুনঃ: rm -f "$TF"দরকার নেই, দেখুন trap ... EXIT। পুনঃ $tfপরিবর্তে $TF: সম্ভবত; এটি স্টাইলের বিষয়।
স্যাট কাটসুরা

এটি ইউনিক্স ফাইল অনুমতিগুলির স্বাভাবিক এবং প্রত্যাশিত আচরণ। আমার বক্তব্যটি হ'ল একটি নতুন ফাইল তৈরি করা এবং এটি মূল উইলের উপরে এমভি-ইন করা result ফলে সেই ফাইলের নামের জন্য একটি নতুন ইনোড হবে (কোনও হার্ড-লিঙ্কগুলি ভঙ্গ করা)। ২. বর্তমান যদি umask মূল পার্ম থেকে পৃথক হয় তবে সম্ভবত পার্মস পরিবর্তন করুন । বড় হাতের ভার্সনের ক্ষেত্রে, এটি কেবল স্টাইলের বিষয় নয় - প্রচুর লোক যারা বড় হাতের পাথ বা র্যান্ডম বা শেল ব্যবহার করতে ভুল করেছেন বা তাদের নিজস্ব ভেরিয়েবলের জন্য যা কিছু কঠিন উপায় খুঁজে পেয়েছে। (এবং হ্যাঁ, আমি প্রায়শই বড় হাতের ভারগুলি নিজেই ব্যবহার করি I আমি জানি এটি ভুল, আমি অভ্যাসটি ভাঙার চেষ্টা করছি)।
সি এ এস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.