কোনও ফাইলের ইনপ্লেস পরিবর্তন কীভাবে করা হচ্ছে?


10

উদাহরণস্বরূপ sed -iবা এর মাধ্যমে কোনও ফাইলের "অন্তর্নিহিত" পরিবর্তনটি perl -iকী বোঝায়?
আমার প্রশ্নটি এই ইনপ্লেস পরিবর্তনটি কীভাবে করা হয় সে সম্পর্কে। ফাইলটি অনুলিপি করা হয়েছে কি অনুলিপিটি অনুলিপি করা হয় এবং তারপরে আসলটি প্রতিস্থাপন করা হয়? অথবা মূল ফাইলটি কোনওভাবে পরিবর্তিত হচ্ছে?


এই বিষয়ের বিশদ ব্যাখ্যার জন্য backreferences.org/2011/01/29/in-place-editing-of-filesএকবার দেখুন ।
scy

এই বিষয়টির জন্য, এটি দিয়ে exবা কীভাবে করা হয় vi?
ওয়াইল্ডকার্ড

@ উইল্ডকার্ড - এদের প্রত্যেকেরই একটি পুরো সিস্টেম রয়েছে। exএকটি মেইল ​​ফাইল (যেমন, dead.mailবা আপনার মধ্যে কিছু এবং আপনার মেইল ​​স্পুলারের কাছাকাছি অন্য কোথাও সাধারণত সাধারণত) বজায় রাখে । চশমাগুলি পরীক্ষা করে দেখুন - তাদের প্রত্যেকের রাষ্ট্রের দৈর্ঘ্য সংজ্ঞায়িত হয়েছে ... exবেশিরভাগ ক্ষেত্রে এর নিজস্ব বাইনারি ফর্ম্যাট রয়েছে (আপনার -rescueফাইলটি দেখুন) এবং এটি পৃথক অস্থায়ী বাফার ফাইলগুলি (সম্ভবত ছয়টি হিসাবে বেশি) প্রিজারোতে ব্যবহৃত হয় । সুতরাং এই বাফারগুলি সম্পাদনা করতে ইনপুট ব্লকগুলি অনুলিপি করে আনস সিঙ্ক পরিবর্তনগুলি প্রতি অফসেটগুলিতে লিখবে :!written?
মাইক্রজারভ

উত্তর:


18

sed একটি অস্থায়ী ফাইল তৈরি করে, সেই ফাইলে আউটপুট লেখেন এবং তারপরে অস্থায়ী ফাইলটির নামটির মূলটির শীর্ষে রাখবেন।

আপনি যা ব্যবহার করে তা দেখতে পারেন strace:

$ strace -e trace=file sed -i -e '' a
execve("/usr/bin/sed", ["sed", "-i", "-e", "", "a"], [/* 34 vars */]) = 0
<...trimmed...>
open("a", O_RDONLY)                     = 3
open("./sedxvhRY8", O_RDWR|O_CREAT|O_EXCL, 0600) = 4
rename("./sedxvhRY8", "a")              = 0
+++ exited with 0 +++

এটি সমস্ত ফাইল অপারেশনগুলিতে লগ sedকরে: এটি একটি নতুন ফাইল তৈরি করে (নিরাপদে এটি দিয়ে O_CREAT|O_EXCL), এতে ডেটা লিখে এবং তারপরে এটি আমার মূল ফাইলের শীর্ষে ফিরিয়ে নিয়ে যায় a

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

perl সাম্প্রতিক সংস্করণগুলিতে ইনপুট ফাইলটি খোলে, তারপরে এটি মুছে ফেলা হয় এবং একই নামে একটি নতুন ফাইল তৈরি করে:

open("a", O_RDONLY)               = 3
unlink("a")                       = 0
open("a", O_WRONLY|O_CREAT|O_EXCL, 0600) = 4

unlinkআপনি ইতিমধ্যে খোলা কোনও ফাইল মুছে ফেলার সময় আপনি যতক্ষণ হ্যান্ডেলটি চারদিকে রাখছেন ততক্ষণ আপনি এতে অ্যাক্সেস ধরে রাখবেন, যাতে এটি মুছে ফেলা ফাইলটির বাইরে থাকা ডেটা পড়তে পারে can এইভাবে perlকোনও অস্থায়ী ফাইলের পরিবর্তে আউটপুট ফাইলটিতে সরাসরি লিখুন: কোনও অতিরিক্ত ফাইল তৈরি করা হয় না, তবে আপনি যদি প্রক্রিয়া চলাকালীন ফাইলটি পড়েন তবে আপনি আংশিক বিষয়বস্তু পাবেন, sedএর পদ্ধতির সাথে ভিন্ন unlike এখানে একটি সংক্ষিপ্ত সময় রয়েছে যখন সঠিক নাম সহ কোনও ফাইল নেই, যা প্রক্রিয়াটি শুরু হওয়ার পরিবর্তে (যেমন হিসাবে sed -i .bak) শুরু হয়।


sedএবং উভয়ই perl:

  • একটি সাধারণ ফাইলের সাথে একটি প্রতীকী লিঙ্কটি প্রতিস্থাপন করুন।
  • শক্ত লিঙ্কগুলি বিরতি দিন।
  • সম্ভব হলে গোষ্ঠীর মালিকানা রক্ষা করুন।
  • আপনার ডিফল্ট গোষ্ঠী (বা সেই ডিরেক্টরিটি যদি setgidবিট থাকে তবে মূল ডিরেক্টরিটির গোষ্ঠী) দিয়ে ফাইলটি তৈরি করুন যদি এটি এমন কোনও গ্রুপের মালিকানাধীন যেখানে আপনি নেই এবং আপনি রুট নন।
  • আপনি যদি রুট হন তবে ফাইলের মালিকানা সংরক্ষণ করুন।
  • প্রাথমিক অনুমতি সংরক্ষণ করুন।
  • ফলাফল setuidএবং setgrpবিটগুলি সংরক্ষণ করুন , যদি ফলাফলের গোষ্ঠীটি শুরু হওয়া গোষ্ঠীর সমান হয়।
  • স্টিকি বিট সংরক্ষণ করুন।
  • এক্সটার্স সংরক্ষণ করা হয় না

sed ইচ্ছাশক্তি:

  • এসিএল সংরক্ষণ করুন (লিনাক্সে; আমি অন্যদের সম্পর্কে জানি না)

perl ইচ্ছাশক্তি:

  • এসিএল সংরক্ষণ করবেন না

উপরেরটি জিএনইউযুক্ত লিনাক্স sedএবং ম্যাক ওএস এক্স এর (ফ্রিবিএসডি-প্রাপ্ত) দ্বারা সত্য sed


3

@ হোমারের উত্তর ছাড়াও, থেকে perldoc perlrun:

"<>" নির্মাণের মাধ্যমে প্রক্রিয়া করা ফাইলগুলি স্থানে সম্পাদনা করতে হবে তা সুনির্দিষ্ট করে। এটি ইনপুট ফাইলটির নাম পরিবর্তন করে, আদি নাম দিয়ে আউটপুট ফাইলটি খোলার মাধ্যমে এবং মুদ্রণ () বিবৃতিগুলির জন্য ডিফল্ট হিসাবে আউটপুট ফাইলটি নির্বাচন করে এটি করে। এক্সটেনশনটি সরবরাহ করা থাকলে, এই নিয়মগুলি অনুসরণ করে একটি ব্যাকআপ কপি তৈরি করতে পুরানো ফাইলটির নাম পরিবর্তন করতে ব্যবহৃত হয়:

যদি কোনও এক্সটেনশান সরবরাহ না করা হয় তবে কোনও ব্যাকআপ তৈরি করা হয় না এবং বর্তমান ফাইলটি ওভাররাইট করা হয়।

যদি এক্সটেনশনে কোনও * থাকে না, তবে এটি প্রত্যয় হিসাবে বর্তমান ফাইলের নামের শেষে যুক্ত হবে। যদি এক্সটেনশানটিতে এক বা একাধিক * অক্ষর থাকে তবে প্রতিটি * বর্তমান ফাইলের নামের সাথে প্রতিস্থাপিত হয়।

এবং মনে রাখবেন যে কোনও নরম লিঙ্ক বা হার্ড লিঙ্ক সংরক্ষণ করা হয়নি:

মনে রাখবেন যে -i একই নামের নতুন ফাইল তৈরি করার আগে আসল ফাইলটির নাম পরিবর্তন করে বা মুছে দেয়, ইউনিক্স-স্টাইলের নরম এবং হার্ড লিঙ্কগুলি সংরক্ষণ করা হবে না।

অবশেষে, -i স্যুইচ কমান্ড লাইনে কোনও ফাইল না দিলে মৃত্যুদন্ড কার্যকর করতে বাধা দেয় না। এই ক্ষেত্রে, কোনও ব্যাকআপ তৈরি হয় না (আসল ফাইলটি অবশ্যই নির্ধারণ করা যায় না) এবং প্রসেসিংটি STDIN থেকে STDOUT পর্যন্ত প্রত্যাশিত হিসাবে এগিয়ে যায়।

এটি আপনাকে বিকল্পের -iসাথে কেন ব্যবহার করতে হবে -pবা printআপনি যদি অভ্যন্তরীণ সাথে সম্পাদনা করতে চান তবে একটি স্পষ্ট বিবৃতি ব্যবহার করতে হবে তাও এটি ব্যাখ্যা করে perl:

# Opps, file will be truncated, becomes empty
$ perl -i.bak -ne 's/123/qwe/' file

# Right way
$ perl -i.bak -ne 's/123/qwe/;print' file

# Or
$ perl -i.bak -pe 's/123/qwe/' file
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.