সোলারিসে "সেড-আই" কমান্ডের কোনও বিকল্প আছে কি?


11

আমার প্রজেক্টে একটি প্রয়োজনীয় কিছু ফাইলের মতো fooকিছু ফাইলের পরিবর্তে এমন কিছু পাঠ্য যেমন fooofoo:

abc.txt
name
foo
foo1

সুতরাং আমি চেষ্টা করেছি:

sed -i "s/foo/fooofoo/g" abc.txt

তবে আমি এই ত্রুটিটি পেয়েছি:

সেড: অবৈধ বিকল্প - i

আমাকে যে ম্যানুয়ালটি ব্যবহার করতে হবে তা পেয়েছি:

sed -i\ "s/foo/fooofoo/g" abc.txt

তবে এটিও কাজ করছে না।

আমি বিকল্প পাওয়া perlএবং awkএছাড়াও কিন্তু সোলারিস মধ্যে একটি সমাধান sedঅনেক প্রশংসা হবে।

আমি ব্যাশের এই সংস্করণটি ব্যবহার করছি:

জিএনইউ বাশ, সংস্করণ ৩.২.৫ 1 (১) রিলিজ (স্পার্ক-সান-সোলারিস ২.১০)


সোলারিস 11 এবং তারপরে, /usr/gnu/bin/sed-i সমর্থন পেতে কেবল ব্যবহার করুন ।
16:40

উত্তর:


15

ব্যবহার ed। এটি বেশিরভাগ প্ল্যাটফর্মগুলিতে উপলভ্য এবং এটি আপনার ফাইলগুলিকে স্থানে সম্পাদনা করতে পারে।
যেহেতু নিদর্শনগুলি প্রতিস্থাপনের জন্য সিনট্যাক্সের sedউপর ভিত্তি করে edএকই রকম:

ed -s infile <<\IN
,s/old/new/g
w
q
IN

এর edপরিবর্তে কেন exশুধু কৌতূহলী? (আমি জানি উভয়ই পসিক্স অনুগত এবং আমি চশমা যুক্ত করেছি;)))
ওয়াইল্ডকার্ড

1
@ উইল্ডকার্ড - আমি বিপরীতটি জিজ্ঞাসা করতে পারি - কেন ex? আপনার প্রশ্নের উত্তর দেওয়ার জন্য: যেহেতু আমি কখনই ব্যবহার ex করি না আমি এর সাথে পরিচিত নই। বিটিডব্লিউ, আমি এমন সেটআপগুলি দেখেছি যেখানে edউপস্থিত ছিল কিন্তু exছিল না (তবে বিপরীতে নয়) ... আমার ল্যাপটপটি সবচেয়ে উল্লেখযোগ্য হচ্ছে :)
ডোন_ক্রিসটি

ভাল উত্তর. :) আমার উত্তর: যেহেতু আমি সবসময় ভিম ব্যবহার করি, তাই আমি exআদেশের সাথে খুব পরিচিত । viআপনি যে সমস্ত কমান্ড কলোন দিয়ে শুরু করতে পারেন তা হ'ল exআদেশ। অবশ্যই কয়েকটি ভিম-নির্দিষ্ট এক্সটেনশন রয়েছে, তবে কেবলমাত্র কমান্ডের মূল সেটটি অবিশ্বাস্যভাবে শক্তিশালী এবং নমনীয় এবং স্ক্রিপ্টযুক্ত সম্পাদনাগুলির জন্য যথেষ্ট।
ওয়াইল্ডকার্ড

আমার মাঞ্জারো সিস্টেমটি আছে exএবং এখনও নেই ed
মাঝামাঝি

8

আপনি যদি GNU সেড ইনস্টল করতে না পারেন তবে ব্যবহার করুন:

sed "s/foo/fooofoo/g" abc.txt >abc.tmp && mv abc.tmp abc.txt

এটি অস্থায়ী ফাইলে সেড আউটপুট প্রেরণে পুনঃনির্দেশ ব্যবহার করে । যদি সেডটি সফলভাবে সম্পূর্ণ হয় তবে abc.txtএটি অস্থায়ী ফাইলের সাথে ওভাররাইট করে।

জিএনইউ সিডের উত্স কোড থেকে দেখা যায় , এটি ঠিক তাই sed -iকরে। সুতরাং, এটি প্রায় হিসাবে দক্ষ হিসাবে sed -i

যদি abc.tmpইতিমধ্যে ইতিমধ্যে বিদ্যমান এমন কোনও সুযোগ থাকে তবে আপনি mktempঅস্থায়ীর জন্য অনন্য নাম তৈরি করতে আপনি ব্যবহার করতে পারেন বা অনুরূপ কোনও ইউটিলিটি।


সাহায্যের জন্য ধন্যবাদ. তবে সোলারিতে কি এমন কোনও বিকল্প রয়েছে যার দ্বারা আমরা একটি অস্থায়ী ফাইল তৈরি না করে বিদ্যমান ফাইলটি আপডেট করতে পারি?
tpsaitwal

10
এটি আপনার কাছে ভঙ্গ করতে ঘৃণা করে তবে সেড এমনকি একটি অস্থায়ী ফাইল তৈরি করে। git.savannah.gnu.org/cgit/sed.git/tree/sed/sed.c#n84
জেফ

1
আপনি যদি হার্ড লিঙ্কগুলির বিষয়ে চিন্তা না করেন তবে আপনি এটি করতে পারেন - আমার উদাহরণ দেখুন। এখনও একটি অস্থায়ী ফাইল রয়েছে, তবে এটি লুকানো (নামবিহীন)। একটি অস্থায়ী ছাড়া, আপনার ব্যবহার করা দরকার ed, যেহেতু এটি পুরো ফাইলটিকে মেমরিতে পড়ে।
টবি স্পিড

3

আপনি যদি এর সমতুল্য চান তবে sed -i.bakএটি বেশ সহজ।

জিএনইউ সিডের জন্য এই স্ক্রিপ্টটি বিবেচনা করুন:

#!/bin/sh

# Create an input file to demonstrate
trap 'rm -r "$dir"' EXIT
dir=$(mktemp -d)
grep -v '[[:upper:][:punct:]]' /usr/share/dict/words | head >"$dir/foo"

# sed program - removes 'aardvark' and 'aardvarks'
script='/aard/d'

##########
# What we want to do
sed -i.bak -e "$script" "$dir"
##########

# Prove that it worked
ls "$dir"
cat "$dir/foo"

আমরা কেবল চিহ্নিত লাইনটি এর সাথে প্রতিস্থাপন করতে পারি

cp "$dir/foo" "$dir/foo.bak" && sed -e "$script" "$dir/foo.bak" >"$dir/foo"

এটি বিদ্যমান ফাইলটিকে ব্যাকআপ হতে সরিয়ে দেয় এবং একটি নতুন ফাইল লেখায়।

আমরা যদি এর সমতুল্য চাই

sed -i -e "$script" "$dir"  # no backup

তাহলে এটি কিছুটা জটিল। আমরা স্ট্যান্ডার্ড ইনপুট হিসাবে ফাইলটি পড়ার জন্য খুলতে পারি, তারপরে সেডের আউটপুটটি প্রতিস্থাপনের আগে এটি লিঙ্কমুক্ত করতে পারি:

( cp "$dir/foo" "$dir/foo.bak"; exec <"$dir/foo.bak"; rm "$dir/foo.bak"; exec sed -e "$script" >"$dir/foo" )

আমরা এটি একটি সাব-শেলের মাধ্যমে করি, যাতে আমাদের মূল স্ট্ডিন এর পরেও উপলব্ধ। ইনপুটগুলি স্যুইচেল করা এবং সাবসেল ছাড়াই ফিরে স্যুইচ করা সম্ভব, তবে এই উপায়টি আমার কাছে আরও স্পষ্ট মনে হয়।

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


3

প্রথমত, আপনার জানা উচিত যে আপনি যে i\আদেশটি উল্লেখ করছেন সেটি হ'ল পাঠ্যের একটি লাইন সন্নিবেশ করানোর জন্য - সম্পাদিত পাঠ্যটি ফাইলে ফিরে সংরক্ষণ করার জন্য নয়। কোন নেই POSIX-নির্দিষ্ট পথ ব্যবহার করতে sedযে জন্য।

আপনি কি করতে পারেন কি ব্যবহার ex, যা করা হয় POSIX দ্বারা নির্দিষ্ট :

printf '%s\n' '%s/find/replace/g' 'x' | ex file.txt

xকমান্ড জন্য "সংরক্ষণ করে প্রস্থান।" আপনি ব্যবহার করতে পারেন wqতবে xসংক্ষিপ্ত।

%বিকল্প কমান্ড মানে শুরুতে চিহ্ন, "বাফারে যে লাইনে এই কমান্ড প্রয়োগ করুন।" আপনি এটি ব্যবহার করতে 1,$s/find/replace/gপারে।


মধ্যে একটা বড়ো ভিন্নতা exএবং sedযে sedএকটি হল প্রবাহ এডিটর। এটি কেবল ক্রমান্বয়ে পরিচালিত হয়, এক এক করে লাইন। exএর চেয়ে অনেক বেশি নমনীয় এবং বাস্তবে আপনি সরাসরি ইন্টারেক্টিভ পাঠ্য ফাইল সম্পাদনা করতে পারেন ex। এটি তাত্ক্ষণিক পূর্বসূরী vi


1

অস্থায়ী ফাইল ব্যবহার করা sedএবং কোনও দৃশ্যমান নয় :

আপনি পৃথক দৃশ্যমান "টেম্প ফাইল" তৈরি এড়াতে পারবেন :

exec 3<abc.txt
rm abc.txt
sed 's/foo/fooofoo/' <&3 >abc.txt
exec 3<&-

ব্যাখ্যা

ইউনিক্সের মত সিস্টেম আসলে ডিস্ক থেকে ফাইলের বিষয়বস্তু অপসারণ না হওয়া পর্যন্ত এটা উভয় ফাইল সিস্টেম এ লিঙ্কমুক্ত, এবং কোন প্রক্রিয়ায় খোলা নেই। সুতরাং আপনি ফাইল বিবরণকারী exec 3<3, rmফাইলটি (যা এটি ফাইল সিস্টেম থেকে লিঙ্কমুক্ত করে) পড়ার জন্য শেলটিতে ফাইলটি খোলার জন্য করতে পারেন এবং তারপরে sedইনপুট হিসাবে ব্যবহৃত ফাইল বর্ণনাকারী 3 দিয়ে কল করতে পারেন।

মনে রাখবেন এটি এর থেকে খুব আলাদা:

# Does not work.
sed 's/foo/fooofoo/' <abc.txt >abc.txt

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

তারপরে আপনার কাজ শেষ হয়ে গেলে, আপনি আগে খোলার ফাইল বিবরণকারীটি বন্ধ করতে পারেন (এটিই exec 3<&-বিশেষ সিনট্যাক্সটি করে) যা মূল ফাইলটি প্রকাশ করে যাতে অপারেটিং সিস্টেমটি তার ডিস্কের স্থানটি (অব্যবহৃত হিসাবে চিহ্নিত করতে পারে) মুছে ফেলতে পারে।

আদেশ সহকারে

এই সমাধানটি সম্পর্কে মনে রাখার জন্য কয়েকটি জিনিস রয়েছে:

  1. আপনি কেবল বিষয়বস্তুগুলির মধ্যে একটি "যেতে" পান - ফাইলের বিবরণীতে শেলটির "সন্ধান" করার কোনও পোর্টেবল উপায় নেই - সুতরাং যখন কোনও প্রোগ্রাম কিছু বিষয়বস্তু পড়ে, অন্য প্রোগ্রামগুলি কেবল ফাইলটির বাকী অংশটি দেখতে পাবে। এবং sedপুরো ফাইলটি পড়বে।

  2. আপনার শেল / স্ক্রিপ্ট / সেডটি শেষ হয়ে যাওয়ার আগে যদি মারা যায় তবে আপনার আসল ফাইলটি নষ্ট হওয়ার খুব কম সম্ভাবনা রয়েছে।


স্পষ্টতই, @ টবিস্পাইটটি ইতিমধ্যে তার উত্তরের শেষে এই সমাধানের একটি উদাহরণ পোস্ট করেছে, তবে আমি ভেবেছিলাম এটি আরও গভীরতর বিবরণ ব্যবহার করতে পারে।
mtraceur

ডাউনওয়োটারের কাছে: যদিও আমি নিশ্চিত যে একটি ডাউনভোট রেখে যাওয়া আপনাকে নিজের সম্পর্কে ভাল বোধ করে, আমি এই উত্তরটি নিয়ে আপনার কী সমস্যা রয়েছে, কীভাবে এটি উন্নত করা যেতে পারে ইত্যাদি সম্পর্কে প্রতিক্রিয়া জানিয়ে আপনি যদি আরও অবদান রাখেন তবে আমি প্রশংসা করব appreciate ।
mtraceur

হতে পারে আপনি পার্ল -i
c4f4t0r

@ c4f4t0r: দেরী জবাবের জন্য দুঃখিত: হ্যাঁ, perl -iঅন্য একটি ভাল বিকল্প। প্রশ্নটি সোলারিসের সাথে সামঞ্জস্যপূর্ণ সমাধানের অনুরোধ করেছে, এর সমাধানগুলির sedবিপরীতে perlএবং awkতারা ইতিমধ্যে অনুসন্ধানের কথা উল্লেখ করেছে। এছাড়াও, আমার উত্তরটি মূলত এমন কিছু যুক্ত করার উদ্দেশ্যে তৈরি করা হয়েছিল যা আমি মনে করি যে এটি দরকারী এবং অন্য যে কোনও উত্তর থেকে অনুপস্থিত।
mtraceur
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.