পার্ল -i বানানোর কোনও উপায় কি ক্লোবার সিমলিংক না?


12

আমার এক বন্ধু যে পয়েন্ট আউট আপনি কি যদি:

perl -pi.bak -e 's/foo/bar/' somefile

যখন "somefile" আসলে একটি সিমবলিক লিঙ্ক হয়, পার্ল শুধু করে ডক্স বলতে কি এটা করতে হবে:

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

যার ফলস্বরূপ একটি নতুন সিমলিংক "somefile.bak" অপরিবর্তিত আসল ফাইলটির দিকে ইঙ্গিত করে, এবং একটি নতুন, পরিবর্তিত নিয়মিত ফাইল "সামিয়ার ফাইল" পরিবর্তিত হয়।

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

( sedএকই জিনিস, এটি মূল্য কি জন্য।)


1
ভিম বা ইমাসকে কল করুন (আমি মনে করি উভয়ই সিমলিঙ্কগুলি অনুসরণ করে)? সিরিয়াসলি, আমি আশঙ্কা উত্তর reimplement হয় -p -iআপনার স্ক্রিপ্টের মধ্যে।
গিলস 21'20

শেড আসলে একই কাজ করে না, কমপক্ষে ২০০৯ সালের জুনে প্রকাশিত সংস্করণ ৪.২.১ থেকে নয় You সিমলিংকের ক্লোবার্বিংয়ের পরিবর্তে লিঙ্ক-টু ফাইল সম্পাদনা করার জন্য আপনাকে অবশ্যই - ফলো-সিমলিংক বিকল্পটি অন্তর্ভুক্ত করতে হবে ; আমি ধরে নিয়েছি এটি বিদ্যমান স্ক্রিপ্টগুলির ভাঙ্গন এড়ানোর জন্য করা হয়েছিল যা পুরানো আচরণের উপর নির্ভর করে।
গ্যারেট 16

উত্তর:


6

আমি ভাবছি কিনা ছোট spongeসাধারণ ইউটিলিটি ( "একটি ফাইলে মান ইনপুট এবং লেখার আপ শোষণ") থেকে moreutils সহায়ক এই ক্ষেত্রে হতে হবে এবং এটি সিমবলিক লিঙ্ক অনুসরণ করা হবে কিনা।

লেখক বর্ণনা sponge ভালো:

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

আমি সাধারণত স্পঞ্জটি কিছুটা এরকম ব্যবহার করি:

sed '...' file | grep '...' | sponge file

ওহে দুর্দান্ত, কাজ করে। আমার সন্দেহ হয় উপরের গিলসের মন্তব্যটি "আসল" উত্তর, কিন্তু যেহেতু তিনি এটিকে উত্তর হিসাবে তৈরি করেননি এবং যেহেতু আমি একটি নতুন উপযোগিতা শিখি, আমি এটি গ্রহণ করব। :)
ম্যাটডেম

কিন্তু আপনি পরীক্ষা আছে spongeবাস্তবে যেমন একটি ব্যবহারের জন্য? আমার হিসাবে: এখনও না। আপনি এখানে দয়া করে পরীক্ষাতে আচরণ করেছেন কিনা তা জানিয়ে কোনও মন্তব্য করতে পারেন? ওহ, আমি মন্তব্য দেখুন। নিশ্চিত করার জন্য ধন্যবাদ!
ইম্জ - ইভান জাখারিয়াশেভ

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

@ ম্যাটডেম: হ্যাঁ, নিশ্চিতকরণের জন্য ধন্যবাদ! (আমি তোমার কথা খেয়াল "যে কাজ করে" একটু পরে চেয়ে আমি আমার মন্তব্য লিখেছে।)
ইভান Zakharyaschev - imz

3

আপনি একটা সত্য যে জন্য জানেন তাহলে somefileএকটি সিমবলিক লিঙ্ক হয়, তাহলে আপনি স্পষ্টভাবে নিম্নলিখিত সঙ্গে ফাইলের সম্পূর্ণ পাথ সরবরাহ করতে পারে:

perl -pi.bak -e 's/foo/bar/' $(readlink somefile)

এই পদ্ধতিতে, মূল সিমলিংক অক্ষত থাকে কারণ প্রতিস্থাপনটি এখন সরাসরি সরাসরি মূল ফাইলের সাথে সম্পন্ন হয়।


তবে এর ফলাফল readlinkএখনও অন্য একটি সিমিলিংক হতে পারে। শ্রেষ্ঠ ব্যবহার করতে হবে -fবা -eকোথায় পাওয়া যায় বা zshএর $file:Pবা (:P)কোয়ালিফায়ার উল্লিখিত glob যেমন @ikegami দ্বারা প্রদর্শিত একটি সিমবলিক লিঙ্ক মুক্ত পথ পেতে।
স্টাফেন চেজেলাস

3

আপনি যদি কোনও একক ফাইলের সাথে লেনদেন করেন তবে কমান্ডটি নীচে দেখতে পাবেন:

perl -i -pe'...' -- "$qfn"

সমাধান এর পরে নিম্নলিখিত হল:

perl -i -pe'...' -- "$( readlink -e -- "$qfn" )"

এই উভয় symlinks এবং অ symlinks পরিচালনা করে।


আপনি যদি ইচ্ছামত প্রচুর সংখ্যক ফাইলের সাথে লেনদেন করেন, কমান্ডটি নীচে দেখতে পাবেন:

... | xargs -r perl -i -pe'...' --

সমাধান এর পরে নিম্নলিখিত হল:

... | xargs -r readlink -ze -- | xargs -r0 perl -i -pe'...' --

এই উভয় symlinks এবং অ symlinks পরিচালনা করে।


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

সাবধান থাকুন যে জিএনইউ দিয়ে readlink -e, এমন একটি সিমলিংক যা বিদ্যমান ফাইলে সমাধান করা যায় না, চুপচাপ মুছে ফেলা হয়।


@ স্টাফেন চেজেলাস, $var:Pআমার পক্ষে কাজ করে না। ( X='tmp' zsh -c 'perl -E"say for @ARGV" $X:P'আউটপুট tmp:P)
আইকেগামি

আপনার জন্য zsh 5.3 (2016) বা তার বেশি প্রয়োজন $var:P। পুরানো সংস্করণ সহ, আপনি সর্বদা $var:Aপরিবর্তে ব্যবহার করতে পারেন । পার্থক্যগুলির জন্য ম্যানুয়ালটি দেখুন এবং zsh.org/mla/users/2016/msg00593.html প্রবর্তনের যৌক্তিকতার জন্য :P(আসল realpath()ইন্টারফেস)।
স্টাফেন চেজেলাস

( ২০১২ :Aসালে জিএনইউতে ৪.৩.১০ (২০০৯) এ যুক্ত হয়েছিল readlink -z, আমি readlinkসমর্থন করি এমন কোনও বাস্তবায়ন সম্পর্কে অবগত নই -z)। লক্ষ্য করুন গনুহ সঙ্গে xargs, আপনি সাধারণত চান -rবিকল্প যদি না আপনি গ্যারান্টি ইনপুট খালি রাখা যাবে যাবে। এখানে, এটা কোন বড় চুক্তি (যদি না এর perlকোড একটি রয়েছে BEGIN/ ENDবিবৃতি), আপনি শুধু একটি পেতে চাই -i used with no filenames on the command line, reading from STDIN.যদি এমন ঘটে তাহলে সতর্কবার্তা।
স্টাফেন চেজেলাস

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