কোনও ফাইলের প্রথম উপস্থিতিটি প্রতিস্থাপন করতে সেড কীভাবে ব্যবহার করবেন?


217

আমি বিদ্যমান # অন্তর্ভুক্তির আগে অতিরিক্ত অন্তর্ভুক্ত নির্দেশিকা সহ একটি বৃহত সংখ্যক সি ++ উত্স ফাইল আপডেট করতে চাই। এই ধরণের কাজের জন্য, আমি ফাইলটি পুনরায় লেখার জন্য সেডের সাথে একটি ছোট বাশ স্ক্রিপ্ট ব্যবহার করি।

আমি sedপ্রতিটি ঘটনাকে প্রতিস্থাপনের পরিবর্তে কোনও ফাইলের স্ট্রিংয়ের প্রথম উপস্থিতিটি কীভাবে প্রতিস্থাপন করব ?

যদি আমি ব্যবহার করি

sed s/#include/#include "newfile.h"\n#include/

এটি সমস্ত # অন্তর্ভুক্ত করে প্রতিস্থাপন করে।

একই জিনিস অর্জনের জন্য বিকল্প পরামর্শগুলিও স্বাগত।

উত্তর:


135
 # sed script to change "foo" to "bar" only on the first occurrence
 1{x;s/^/first/;x;}
 1,/foo/{x;/first/s///;x;s/foo/bar/;}
 #---end of script---

বা, যদি আপনি পছন্দ করেন: সম্পাদকের নোট: কেবল জিএনইউতে কাজ করে sed

sed '0,/foo/s//bar/' file 

উৎস


86
আমি মনে করি আমি 'বা আপনি যদি পছন্দ করেন' সমাধানটি পছন্দ করি। উত্তরগুলি ব্যাখ্যা করাও ভাল হবে - এবং উত্তরটির প্রশ্নের উত্তর সরাসরি করা, এবং তারপরে কেবল সাধারণকরণের চেয়ে সাধারণকরণ করা। তবে ভাল উত্তর।
জোনাথন লেফলার

7
ম্যাক ব্যবহারকারীদের জন্য এফওয়াইআই, আপনাকে 0 টি 1 এর সাথে প্রতিস্থাপন করতে হবে, সুতরাং: সেড '1, / আরই / এস // টু_ট্যাট /' ফাইল
mhost

1
@ মিস্ট হোস্ট নং, প্যাটার্নটি # 1 লাইনে পাওয়া গেলে এটি প্রতিস্থাপন করবে এবং প্যাটার্নটি অন্য লাইনে না থাকলেও এটি এখনও প্রথম পাওয়া প্যাটার্ন is PS এটি উল্লেখ করা উচিত যে এটি 0,কেবল সাথে কাজ করেgnu sed
Jotne

11
কেউ দয়া করে 'বা যদি আপনি পছন্দ করেন' সমাধানটি ব্যাখ্যা করতে পারেন? "থেকে" প্যাটার্নটি কোথায় রাখবেন তা আমি জানি না।
জিন-লুক ন্যাসিফ কোয়েলহো

3
@ জিন-লুসনসিফকোয়েলহো: ব্যবহার করা s//- অর্থাত, একটি খালি রেজেক্স - এর অর্থ হল যে সর্বাধিক প্রয়োগ হওয়া রেজেক্স সুস্পষ্টভাবে পুনরায় ব্যবহার করা হয়েছে; এই ক্ষেত্রে RE,। এই সুবিধাজনক শর্টকাট এর অর্থ আপনার sকলটিতে আপনাকে রেঞ্জ-এন্ডিং রিজেক্সের নকল করতে হবে না ।
mklement0

289

একটি sedস্ক্রিপ্ট যা কেবলমাত্র "কলা" দ্বারা "অ্যাপল" এর প্রথম উপস্থিতিকে প্রতিস্থাপন করবে

উদাহরণ

     Input:      Output:

     Apple       Banana
     Apple       Apple
     Orange      Orange
     Apple       Apple

এটি সাধারণ স্ক্রিপ্ট: সম্পাদকের নোট: কেবলমাত্র জিএনইউ নিয়ে কাজ করে sed

sed '0,/Apple/{s/Apple/Banana/}' input_filename

প্রথম দুটি পরামিতি 0এবং /Apple/ব্যাপ্তি নির্দিষ্টকরণকারী। এই s/Apple/Banana/সীমার মধ্যেই কার্যকর করা হয়। সুতরাং এক্ষেত্রে "প্রথম সীমা ( 0) এর প্রথম সীমা পর্যন্ত" এর সাথে Appleপ্রতিস্থাপন করুন Only কেবলমাত্র প্রথমটি প্রতিস্থাপন করা হবে।AppleBananaApple

পটভূমি: প্রথাগত sedপরিসর সুনির্দিষ্টভাবে উল্লেখ করা হয় এছাড়াও "এখানে শুরু" এবং "এখানেই শেষ" (সহ)। তবে সর্বনিম্ন "সূচনা" হ'ল প্রথম লাইন (লাইন 1), এবং যদি "এখানেই শেষ হয়" একটি রেজেক্স হয়, তবে এটি কেবল "শুরু" এর পরে পরবর্তী লাইনের সাথে ম্যাচ করার চেষ্টা করা হয়, সুতরাং প্রথম দিকের প্রথম প্রান্তটি লাইন হয় ২. সুতরাং যেহেতু পরিসীমা অন্তর্ভুক্তিমূলক, ছোটতম সম্ভাব্য পরিসরটি "২ লাইন" এবং সর্বনিম্ন শুরুর পরিসীমাটি দুটি লাইন 1 এবং 2 উভয়ই (যেমন লাইন 1 এ কোনও ঘটনা উপস্থিত থাকে, তবে লাইন 2 এ সংঘটিত পরিবর্তন হবে, এক্ষেত্রে পছন্দসই নয়) )। GNUসেড "সিউডো" হিসাবে নির্দিষ্ট করে শুরু করার অনুমতি দেওয়ার নিজস্ব বিস্তৃতি যোগ করে line 0যাতে পরিসীমাটির শেষ হতে পারে line 1, এটি "কেবল প্রথম লাইন" এর একটি সীমাকে অনুমতি দেয়

বা একটি সরলীকৃত সংস্করণ (একটি খালি আর এর মতো //অর্থ এটির আগে উল্লিখিত সংস্করণটিকে পুনরায় ব্যবহার করতে হবে, সুতরাং এটি সমতুল্য):

sed '0,/Apple/{s//Banana/}' input_filename

আর কোঁকড়া ধনুর্বন্ধনী হয় ঐচ্ছিক জন্য sকমান্ড, তাই এই এছাড়াও সমতূল্য:

sed '0,/Apple/s//Banana/' input_filename

এই সবগুলি sedশুধুমাত্র জিএনইউতে কাজ করে ।

আপনি হোমব্রু ব্যবহার করে ওএস এক্সে জিএনইউ সেড ইনস্টল করতে পারেন brew install gnu-sed


166
মানব ভাষায় অনূদিত: 0 লাইন থেকে শুরু করুন, 'অ্যাপল' না মেলা অবধি অবিরত করুন, কোঁকড়ানো বন্ধনীতে প্রতিস্থাপন সম্পাদন করুন। সিএফআর
মারিওটোমো

8
ওএস এক্স-এ, আমি পেয়েছিsed: 1: "…": bad flag in substitute command: '}'
এলিওটিটিসিবিএল

5
ওএস এক্স-এ @ এলিলিটিটিসিবিএল, ব্যবহার করুন sed -e '1s/Apple/Banana/;t' -e '1,/Apple/s//Banana/'। @ মিখাইলভিএসের উত্তর থেকে (বর্তমানে) নীচে নীচে।
djb

8
বন্ধনীগুলি ছাড়াও কাজ করে:sed '0,/foo/s/foo/bar/'
ইনোকোন্টি

5
আমি পেয়েছি sed: -e expression #1, char 3: unexpected , '`এর সাথে
জোনাথন

56
sed '0,/pattern/s/pattern/replacement/' filename

এটি আমার জন্য কাজ করেছে।

উদাহরণ

sed '0,/<Menu>/s/<Menu>/<Menu><Menu>Sub menu<\/Menu>/' try.txt > abc.txt

সম্পাদকের দ্রষ্টব্য: দু'জনেই কেবল জিএনইউ নিয়ে কাজ করে sed


2
@ ল্যান্ডস এটি অন্যান্য লাইনেও উদাহরণগুলি প্রতিস্থাপন করে; শুধু প্রথম উদাহরণ নয়
সারাত

1
@ সরাত হ্যাঁ, আপনি ঠিক বলেছেন। sed '1,/pattern/s/pattern/replacement/' filenameকেবল তখনই ম্যাকের "প্যাটার্নটি প্রথম লাইনে প্রদর্শিত হবে না" কাজ করে। আমি আমার আগের মন্তব্যটি মুছে ফেলব কারণ এটি সঠিক নয়। বিস্তারিত এখানে পাওয়া যাবে ( linuxtopia.org/online_books/linux_tool_guides/t__sed_faq/… )। অ্যান্ডির উত্তরটি কেবল জিএনইউ সেডের জন্য কাজ করে, তবে ম্যাকের জন্য নয়।
ল্যান্ডিস

45

ব্যাখ্যা সহ পরিপূরক অনেক সহায়ক বিদ্যমান উত্তরগুলির একটি ওভারভিউ :

এখানে উদাহরণগুলি সরলীকৃত ব্যবহারের ক্ষেত্রে ব্যবহার করে: কেবল প্রথম মিলিত লাইনে 'বার' দিয়ে 'ফু' শব্দটি প্রতিস্থাপন করে।
ব্যবহার করার দরুন ANSI সি-উদ্ধৃতিচিহ্ন সহ পংক্তি ( $'...') নমুনা ইনপুট লাইন প্রদান করতে, bash, ksh, অথবা zshশেল হিসাবে অধিকৃত হয়।


sedশুধুমাত্র জিএনইউ :

বেন হফস্টিনের নতুন বিজ্ঞাপন আমাদের দেখায় যে জিএনইউ নীচের 2-ঠিকানা ফর্মটির জন্য POSIX নির্দিষ্টকরণের জন্য একটি এক্সটেনশান সরবরাহ করে : ( এখানে একটি স্বেচ্ছাসেবী নিয়মিত প্রকাশের প্রতিনিধিত্ব করে)।sed0,/re/re

0,/re/খুব প্রথম লাইনেও রেজেক্স মেলানোর অনুমতি দেয় । অন্য কথায়: এই জাতীয় ঠিকানাটি 1 ম লাইন থেকে শুরু করে এবং মেলে এমন লাইন সহ একটি পরিসীমা তৈরি করবে re- re1 ম লাইনে বা পরবর্তী কোনও লাইনে ঘটে কিনা ।

  • POSIX-অনুবর্তী ফর্ম সঙ্গে এই তুলনা 1,/re/, যা একটি সীমার সৃষ্টি যে 1 ম লাইন থেকে ম্যাচ এবং লাইন সহ যে ম্যাচ reউপর পরবর্তী লাইন; অন্য কথায়: এটি কোনও reমিলের প্রথম ঘটনাটি সনাক্ত করবে না যদি এটি 1 ম লাইনে ঘটে থাকে এবং সর্বাধিক ব্যবহৃত রেজেক্স পুনরায় ব্যবহারের জন্য শর্টহ্যান্ডের ব্যবহারকে বাধা দেয়// (পরবর্তী পয়েন্টটি দেখুন)। 1

আপনি যদি একটি একত্রিত যদি 0,/re/একটি সঙ্গে ঠিকানা s/.../.../(প্রতিকল্পন) কলের ব্যবহার করে একই রেগুলার এক্সপ্রেশন, আপনার আদেশ কার্যকরভাবে শুধুমাত্র প্রতিকল্পন পারফর্ম করবে প্রথম লাইন যে ম্যাচ reসর্বাধিক প্রয়োগ হওয়া নিয়মিত এক্সপ্রেশনটি পুনঃব্যবহারের জন্য
sed একটি সুবিধাজনক শর্টকাট সরবরাহ করে : একটি খালি ডিলিমিটার জুটি// ,।

$ sed '0,/foo/ s//bar/' <<<$'1st foo\nUnrelated\n2nd foo\n3rd foo' 
1st bar         # only 1st match of 'foo' replaced
Unrelated
2nd foo
3rd foo

একজন POSIX-অতিরিক্ত বৈশিষ্ট্যগুলিও উপস্থিত রয়েছে শুধুমাত্র sedএমন বাসদ (MacOS) হিসেবেsed (এছাড়াও হবে সঙ্গে কাজ গনুহ sed ):

যেহেতু 0,/re/ব্যবহার করা যাবে না এবং ফর্মটি 1,/re/সনাক্ত করা যাবে না reযদি এটি প্রথম লাইনে ঘটে থাকে (উপরে দেখুন), 1 ম লাইনের জন্য বিশেষ হ্যান্ডলিং প্রয়োজন

মিখাইলভিএস এর উত্তরে কৌশলটির উল্লেখ রয়েছে, এখানে একটি ਠੋম উদাহরণ দেওয়া হয়েছে:

$ sed -e '1 s/foo/bar/; t' -e '1,// s//bar/' <<<$'1st foo\nUnrelated\n2nd foo\n3rd foo'
1st bar         # only 1st match of 'foo' replaced
Unrelated
2nd foo
3rd foo

বিঃদ্রঃ:

  • খালি রেজেক্স //শর্টকাট এখানে দু'বার নিযুক্ত করা হয়েছে: একবার পরিসীমাটির শেষ পয়েন্টের জন্য, এবং একবার sকল করার জন্য; উভয় ক্ষেত্রেই, রেজেক্স fooসুস্পষ্টভাবে পুনঃব্যবহার করা হয়, যা আমাদের এটির নকল করতে না দেয়, যা সংক্ষিপ্ত এবং আরও বজায় রাখা কোড উভয়ের জন্যই তৈরি করে।

  • প্যাসিক্সের sedনির্দিষ্ট ফাংশনগুলির পরে প্রকৃত নিউলাইনগুলি দরকার যেমন লেবেলের নাম বা তার বাদ পড়ার পরে যেমন tএখানে রয়েছে; কৌশলগতভাবে স্ক্রিপ্টটিকে একাধিক -eবিকল্পে বিভক্ত করা একটি আসল নিউলাইনগুলি ব্যবহারের বিকল্প: প্রতিটি -eস্ক্রিপ্টের অংশ শেষ করুন যেখানে একটি নিউলাইন সাধারণত যেতে হয়।

1 s/foo/bar/fooসেখানে পাওয়া গেলে কেবল 1 ম লাইনে প্রতিস্থাপন করে। যদি তা হয়, tস্ক্রিপ্টের শেষে শাখাগুলি (লাইনে থাকা অবশিষ্ট কমান্ডগুলি এড়িয়ে যায়)। ( tকেবলমাত্র সাম্প্রতিক sকলটি যদি একটি আসল প্রতিস্থাপন সম্পাদন করে তবে একটি লেবেলে ফাংশনটি শাখা করে ; লেবেলের অভাবে, এখানে যেমন রয়েছে, স্ক্রিপ্টের শেষটি ব্রাঞ্চ করা হয়েছে)।

যখন এটি ঘটে তখন রেঞ্জের ঠিকানা 1,//, যা সাধারণত লাইন 2 থেকে শুরু হওয়া প্রথম ঘটনাটি খুঁজে পায় , মিলবে না এবং সীমাটি প্রক্রিয়া করা হবে না , কারণ বর্তমান লাইনটি ইতিমধ্যে থাকলে ঠিকানাটি মূল্যায়ন করা হয় 2

বিপরীতভাবে, সেখানে 1 ম লাইনে কোনো মিল খুঁজে পাওয়া যদি, 1,// হবে প্রবেশ করা, এবং সত্য প্রথম ম্যাচ পাবেন।

নেট প্রভাব গনুহ সঙ্গে হিসাবে একই sedএর 0,/re/শুধুমাত্র প্রথম সংঘটন প্রতিস্থাপিত হয় কিনা এটা 1 ম লাইন বা অন্য কোন উপর ঘটে।


নন-রেঞ্জের পন্থা

potong এর উত্তর প্রমান লুপ কৌশল যে কাজ করার জন্য প্রয়োজন বাইপাস ; যেহেতু তিনি জিএনইউ sed সিনট্যাক্স ব্যবহার করেন , এখানে পসিক্স-কমপ্লায়েন্ট সমতুল্য :

লুপ কৌশল 1: প্রথম ম্যাচে, প্রতিস্থাপনটি সম্পাদন করুন, তারপরে একটি লুপ প্রবেশ করুন যা কেবলমাত্র বাকী রেখাগুলি যেমন প্রিন্ট করে :

$ sed -e '/foo/ {s//bar/; ' -e ':a' -e '$!{n;ba' -e '};}' <<<$'1st foo\nUnrelated\n2nd foo\n3rd foo'
1st bar
Unrelated
2nd foo
3rd foo

লুপ কৌশল 2, কেবল ছোট ছোট ফাইলগুলির জন্য : সম্পূর্ণ ইনপুটটিকে মেমরির মধ্যে পড়ুন, তারপরে এটিতে একটি একক প্রতিস্থাপন সম্পাদন করুন

$ sed -e ':a' -e '$!{N;ba' -e '}; s/foo/bar/' <<<$'1st foo\nUnrelated\n2nd foo\n3rd foo'
1st bar
Unrelated
2nd foo
3rd foo

1 1.61803 কি দিয়ে ঘটে উদাহরণ প্রদান 1,/re/সঙ্গে এবং ছাড়া একটি পরবর্তী s//:
- sed '1,/foo/ s/foo/bar/' <<<$'1foo\n2foo'উৎপাদনের $'1bar\n2bar'; উদাহরণস্বরূপ, উভয় লাইন আপডেট করা হয়েছিল, কারণ লাইন সংখ্যাটি 1প্রথম লাইনটির সাথে মেলে, এবং রেজেক্স /foo/- রেঞ্জের শেষ - কেবলমাত্র পরবর্তী লাইনে শুরু করার জন্য তাকাতে হবে । অতএব, উভয় লাইন এই ক্ষেত্রে নির্বাচিত হয়, এবং s/foo/bar/প্রতিস্থাপন তাদের উভয় উপর সঞ্চালিত হয়।
- sed '1,/foo/ s//bar/' <<<$'1foo\n2foo\n3foo' ব্যর্থ : sed: first RE may not be empty(BSD / macOS) এবং sed: -e expression #1, char 0: no previous regular expression(GNU) সহ, কারণ, সেই সময়ে 1 ম লাইনটি প্রক্রিয়াধীন হচ্ছে ( 1রেঞ্জটি শুরু করার জন্য লাইন নম্বরটির কারণে ), এখনও কোনও রেজেক্স প্রয়োগ করা হয়নি, তাই//কিছুই উল্লেখ করে না।
জিএনইউ'র sedবিশেষ 0,/re/বাক্য গঠন ব্যতীত, কোনও লাইন নম্বর দিয়ে শুরু হওয়া যে কোনও ব্যাপ্তি কার্যকরভাবে ব্যবহারকে বিরত রাখে //


25

আপনি অনুরূপ কিছু করতে বিশ্রী ব্যবহার করতে পারেন ..

awk '/#include/ && !done { print "#include \"newfile.h\""; done=1;}; 1;' file.c

ব্যাখ্যা:

/#include/ && !done

"# অন্তর্ভুক্ত" লাইনটি মেলে এবং আমরা ইতিমধ্যে এটি প্রক্রিয়া করি নি তখন statement between এর মধ্যে ক্রিয়া বিবৃতি চালায়।

{print "#include \"newfile.h\""; done=1;}

এটি # newfile.h "অন্তর্ভুক্ত করে, আমাদের উদ্ধৃতিগুলি এড়িয়ে চলতে হবে। তারপরে আমরা সম্পন্ন ভেরিয়েবলটি 1 এ সেট করেছিলাম, যাতে আমরা আরও অন্তর্ভুক্ত না করি।

1;

এর অর্থ "লাইনটি মুদ্রণ করুন" - - 0 মুদ্রণের জন্য একটি খালি অ্যাকশন ডিফল্ট, যা পুরো লাইনটি মুদ্রণ করে। সেড আইএমও :-) এর তুলনায় একটি লাইনার এবং সহজেই বোঝা যায়


4
এই উত্তরটি sed সমাধান, যার উপর নির্ভর চেয়ে বেশি পোর্টেবল GNU কিন্তু ইত্যাদি .. (যেমন অপারেটিং সিস্টেম-এক্স sed sucks!)
জে টেলর

1
এটি সত্যই আরও বোধগম্য, তবে আমার জন্য এটি এটি প্রতিস্থাপনের পরিবর্তে একটি লাইন যুক্ত করে; কমান্ড ব্যবহৃত হয়েছে: awk '/version/ && !done {print " \"version\": \"'${NEWVERSION}'\""; done=1;}; 1;' package.json
সিরিয়াল কিলার

এখানে একই, সবচেয়ে বোধগম্য কমান্ড, তবে এটি এটি প্রতিস্থাপনের পরিবর্তে প্রাপ্ত স্ট্রিংয়ের উপরে একটি লাইন যুক্ত করেছে
ফ্লায়িয়ন

1
উত্তর বেশ পঠনযোগ্য। আমার সংস্করণটি এখানে নতুন লাইন যুক্ত করার পরিবর্তে স্ট্রিং প্রতিস্থাপন করে। awk '/#include/ && !done { gsub(/#include/, "include \"newfile.h\""); done=1}; 1' file.c
ওরসিরিস ডি জং

18

লিনাক্সটোপিয়া সেড এফএকিউ সম্পর্কে উত্তরের একটি বিস্তৃত সংগ্রহ । এটি হাইলাইট করে যে কিছু উত্তর দেওয়া লোকেরা সিডের নন-জিএনইউ সংস্করণে কাজ করবে না, যেমন

sed '0,/RE/s//to_that/' file

নন-জিএনইউ সংস্করণে থাকতে হবে

sed -e '1s/RE/to_that/;t' -e '1,/RE/s//to_that/'

তবে এই সংস্করণটি gnu সেডের সাথে কাজ করবে না।

এখানে একটি সংস্করণ যা উভয়ের সাথে কাজ করে:

-e '/RE/{s//to_that/;:a' -e '$!N;$!ba' -e '}'

উদা:

sed -e '/Apple/{s//Banana/;:a' -e '$!N;$!ba' -e '}' filename

প্রকৃতপক্ষে, উবুন্টু লিনাক্স ভি 16 এবং ফ্রিবিএসডি ভি 10.2 তে কাজ করার পরীক্ষা করা হয়েছে। তোমাকে ধন্যবাদ.
সোপালাজো ডি অ্যারিরেজ

12
#!/bin/sed -f
1,/^#include/ {
    /^#include/i\
#include "newfile.h"
}

এই স্ক্রিপ্টটি কীভাবে কাজ করে: 1 থেকে প্রথমের মধ্যে #include( প্রথম লাইনের পরে 1) রেখার জন্য যদি লাইনটি শুরু হয় #include, তবে নির্দিষ্ট রেখাটি পূর্ববর্তী করুন।

তবে, প্রথমটি #includeযদি লাইন 1 এ থাকে, তবে লাইন 1 এবং পরের দুটি লাইনই #includeরেখাটি চাপবে। আপনি যদি জিএনইউ ব্যবহার করছেন sedতবে এর একটি এক্সটেনশন রয়েছে যেখানে 0,/^#include/(পরিবর্তে 1,) সঠিক কাজ করবে।


11

কেবল শেষে সংখ্যার সংখ্যা যুক্ত করুন:

sed s/#include/#include "newfile.h"\n#include/1

7
দুর্ভাগ্যক্রমে, এটি কাজ করে না। এটি ফাইলের প্রতিটি লাইনে কেবল প্রথম ঘটনা প্রতিস্থাপন করে এবং ফাইলের প্রথম উপস্থিতিটি প্রতিস্থাপন করে না।
ডেভিড ডিববেন

1
অতিরিক্তভাবে, এটি একটি GNU সেড এক্সটেনশান, মানক সেড বৈশিষ্ট্য নয়।
জোনাথন লেফলার

10
হুম ... সময় কেটে যায়। পজিএক্স ২০০৮ / ২০১৩ এর জন্য sedবিকল্প কমান্ডটি সুনির্দিষ্ট করে: [2addr]s/BRE/replacement/flagsএবং নোট করে যে "পতাকাগুলির মান শূন্য বা তার বেশি হতে হবে: n কেবলমাত্র নিদর্শন স্থানের মধ্যে পাওয়া বিআরইয়ের নবম সংস্থার পরিবর্তে "। সুতরাং, কমপক্ষে POSIX ২০০৮ এ, অনুবর্তনটি 1কোনও GNU sedএক্সটেনশন নয়। প্রকৃতপক্ষে, এসইএস / পসিক্স 1997 স্ট্যান্ডার্ডেও এটি সমর্থিত ছিল, তাই আমি ২০০৮ সালে খুব খারাপভাবেই লাইনের বাইরে ছিলাম
জোনাথন লেফলার

7

একটি সম্ভাব্য সমাধান:

    /#include/!{p;d;}
    i\
    #include "newfile.h"
    :a
    n
    ba

ব্যাখ্যা:

  • আমরা # অন্তর্ভুক্ত না হওয়া অবধি লাইনগুলি পড়ুন, এই লাইনগুলি মুদ্রণ করুন এবং তারপরে নতুন চক্র শুরু করুন
  • নতুন অন্তর্ভুক্ত লাইন .োকান
  • একটি লুপ প্রবেশ করান যা কেবল রেখাগুলি পড়বে (ডিফল্ট সেড এছাড়াও এই লাইনগুলি মুদ্রণ করবে), আমরা এখান থেকে স্ক্রিপ্টের প্রথম অংশে ফিরে পাব না

sed: file me4.sed line 4: ":" lacks a label
রজারডপ্যাক

আপাতদৃষ্টিতে সাম্প্রতিক সেড সংস্করণে কিছু পরিবর্তিত হয়েছে এবং খালি লেবেলগুলির আর অনুমতি নেই। উত্তরটি আপডেট করেছেন
মিচনুল

4

আমি জানি এটি একটি পুরানো পোস্ট তবে আমার কাছে একটি সমাধান ছিল যা আমি ব্যবহার করতাম:

grep -E -m 1 -n 'old' file | sed 's/:.*$//' - | sed 's/$/s\/old\/new\//' - | sed -f - file

মূলত প্রথম ঘটনাটি মুদ্রণের জন্য গ্রেপ ব্যবহার করুন এবং সেখানে থামুন। অতিরিক্ত প্রিন্ট লাইন নম্বর যেমন 5:line। পাইপটি সেডের মধ্যে ফেলুন এবং সরিয়ে ফেলুন: এবং এর পরে যে কোনও কিছুই আপনি কেবল একটি লাইন নম্বর দিয়ে রেখে গেছেন। পাইপ এটি সেডে যা শেষ নম্বরটিতে s /.*/ প্রতিস্থাপন করে, যার ফলস্বরূপ একটি 1 লাইন স্ক্রিপ্ট আসে যা ফাইলটিতে স্ক্রিপ্ট হিসাবে চালানোর জন্য সর্বশেষ সেডে পাইপ করা হয়।

সুতরাং যদি রেজেক্স = #includeএবং প্রতিস্থাপন = blahএবং প্রথম উপস্থিতি গ্রেপের সন্ধান 5 লাইনে হয় তবে সর্বশেষের সেডে পাইপ করা ডেটা হবে 5s/.*/blah/

প্রথম ঘটনা প্রথম লাইনে থাকলেও কাজ করে।


আমি সম্পূর্ণরূপে মাল্টিলাইন সেড স্ক্রিপ্টগুলি বা এস এবং একটি লিনেনবার সহ কিছু সহ কম্যান্ডগুলি ঘৃণা করি তাই এই পদ্ধতির সাথে আমি বোর্ডে আছি। আমি আমার ইউসকেস (ব্যাশের সাথে কাজ করে) এর জন্য যা ব্যবহার করেছি তা এখানে: ফাইলপথ = / ইত্যাদি / হোস্ট; প্যাট = '^ \ (127 \ .0; .0 \ .1। * \)'; repl = 'new 1 নিউহোস্টালিয়াস'; সেড $ (আইএফএস =: লিনিয়ারে = ($ (গ্রেপ-ই-এম 1-এন "$ প্যাট" "$ ফাইলপথ"))) এবং & প্রতিধ্বনি $ {রৈখিক [0]}) এস / "$ প্যাট" / "l repl" / "$
ফাইলপথ

এটা কাজ করে। যদিও কেবল sed -f -
সেডের সাথে এগুলি

3

যদি কেউ এখানে সমস্ত লাইনে (আমার মতো) প্রথম উপস্থিতির জন্য কোনও চরিত্র প্রতিস্থাপন করতে আসে তবে এটি ব্যবহার করুন:

sed '/old/s/old/new/1' file

-bash-4.2$ cat file
123a456a789a
12a34a56
a12
-bash-4.2$ sed '/a/s/a/b/1' file
123b456a789a
12b34a56
b12

উদাহরণস্বরূপ 1 থেকে 2 পরিবর্তন করে আপনি সমস্ত সেকেন্ডকে কেবল পরিবর্তে প্রতিস্থাপন করতে পারেন।


2
আপনাকে এই সমস্ত করার দরকার নেই, 's/a/b/'অর্থ match aএবংdo just first match for every matching line
সামভিন

আমি সামভিনের সাথে আছি। এছাড়াও এটি এখানে জিজ্ঞাসিত প্রশ্নের উত্তর দেয় না । আমি এই উত্তরটি মুছে ফেলার পরামর্শ দেব।
সোসোই

প্রশ্নটি ছিল "কোনও ফাইলের প্রথম ঘটনা" "একটি লাইনে প্রথম ঘটনা" নয়
ম্যানুয়েল রোমিও

3

GNU সেডের -zবিকল্পের সাহায্যে আপনি পুরো ফাইলটি এমনভাবে প্রক্রিয়া করতে পারেন যেন এটি কেবল একটি লাইন। এইভাবে একটি s/…/…/পুরো ফাইলটিতে কেবল প্রথম ম্যাচটি প্রতিস্থাপন করবে। মনে রাখবেন: s/…/…/প্রতিটি লাইনে কেবল প্রথম ম্যাচটি প্রতিস্থাপন করে তবে -zবিকল্পটির sedসাথে পুরো ফাইলটিকে একক লাইন হিসাবে বিবেচনা করা হয়।

sed -z 's/#include/#include "newfile.h"\n#include'

সাধারণ ক্ষেত্রে আপনাকে নিজের ছদ্মবেশ প্রকাশটি আবার লিখতে হবে কারণ প্যাটার্ন স্পেসে এখন কেবল একটি লাইনের পরিবর্তে পুরো ফাইলটি ধারণ করে holds কিছু উদাহরণ:

  • s/text.*//হিসাবে আবার লিখতে পারেন s/text[^\n]*//। নিউলাইন চরিত্র বাদে[^\n] সবকিছুর সাথে মেলে । একটি নতুন লাইন পৌঁছানোর আগ পর্যন্ত সমস্ত প্রতীক মিলবে ।[^\n]*text
  • s/^text//হিসাবে আবার লিখতে পারেন s/(^|\n)text//
  • s/text$//হিসাবে আবার লিখতে পারেন s/text(\n|$)//

2

আমি এটি একটি অস্ক স্ক্রিপ্ট দিয়ে করব:

BEGIN {i=0}
(i==0) && /#include/ {print "#include \"newfile.h\""; i=1}
{print $0}    
END {}

তারপরে এটি ছড়িয়ে দিয়ে চালান:

awk -f awkscript headerfile.h > headerfilenew.h

ম্লান হতে পারে, আমি এই নতুন।


2

বিকল্প পরামর্শ হিসাবে আপনি edকমান্ডটি দেখতে চাইতে পারেন ।

man 1 ed

teststr='
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
'

# for in-place file editing use "ed -s file" and replace ",p" with "w"
# cf. http://wiki.bash-hackers.org/howto/edit-ed
cat <<-'EOF' | sed -e 's/^ *//' -e 's/ *$//' | ed -s <(echo "$teststr")
   H
   /# *include/i
   #include "newfile.h"
   .
   ,p
   q
EOF

2

আরএসএস ফিডে প্রতিটি আইটেমে একটি অনন্য টাইমস্ট্যাম্প ampোকানোর জন্য ব্যাশ স্ক্রিপ্টে কাজ করার জন্য অবশেষে আমি এটি পেয়েছিলাম:

        sed "1,/====RSSpermalink====/s/====RSSpermalink====/${nowms}/" \
            production-feed2.xml.tmp2 > production-feed2.xml.tmp.$counter

এটি কেবল প্রথম ঘটনাটি পরিবর্তন করে।

${nowms}পার্ল স্ক্রিপ্ট দ্বারা সেট করা মিলসেকেন্ডে সময় হ'ল স্ক্রিপ্টের $counterমধ্যে লুপ নিয়ন্ত্রণের জন্য ব্যবহৃত কাউন্টার, \পরের লাইনে কমান্ডটি চালিয়ে যাওয়ার অনুমতি দেয়।

ফাইলটি পঠিত হয় এবং স্টডআউট একটি কাজের ফাইলে পুনঃনির্দেশিত হয়।

যেভাবে আমি এটি বুঝতে পারি, 1,/====RSSpermalink====/সেডকে কখন একটি সীমার সীমাবদ্ধতা সেট করে থামানো উচিত এবং তার পরে s/====RSSpermalink====/${nowms}/প্রথম স্ট্রিংটিকে দ্বিতীয়টির সাথে প্রতিস্থাপনের জন্য পরিচিত সেড কমান্ড।

আমার ক্ষেত্রে আমি কমান্ডটি ডাবল উদ্ধৃতি চিহ্নগুলিতে রেখেছি কারণ আমি এটি ভেরিয়েবলগুলির সাথে ব্যাশ স্ক্রিপ্টে ব্যবহার করছি।


2

ফ্রিবিএসডি ব্যবহার করে কোনও ফাইলের প্রক্রিয়াজাতকরণের কোনও বিবৃতি না থাকলে ক্ষেত্রে "কোনও মিল নেই" ত্রুটি edএড়ানো :edinclude

teststr='
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
'

# using FreeBSD ed
# to avoid ed's "no match" error, see
# *emphasized text*http://codesnippets.joyent.com/posts/show/11917 
cat <<-'EOF' | sed -e 's/^ *//' -e 's/ *$//' | ed -s <(echo "$teststr")
   H
   ,g/# *include/u\
   u\
   i\
   #include "newfile.h"\
   .
   ,p
   q
EOF

এই সাতিশয় অনুরূপ Timo এর উত্তর কিন্তু এক বছর পর ওভার যোগ করা হয়েছিল।
জোনাথন লেফলার

2

এটি আপনার (জিএনইউ সেড) কাজ করতে পারে:

sed -si '/#include/{s//& "newfile.h\n&/;:a;$!{n;ba}}' file1 file2 file....

বা স্মৃতি সমস্যা না থাকলে:

sed -si ':a;$!{N;ba};s/#include/& "newfile.h\n&/' file1 file2 file...

0

নিম্নলিখিত কমান্ড একটি ফাইলের মধ্যে একটি স্ট্রিংয়ের প্রথম উপস্থিতি সরিয়ে দেয়। এটি খালি লাইনটিও সরিয়ে দেয়। এটি একটি এক্সএমএল ফাইলে উপস্থাপন করা হয়েছে তবে এটি কোনও ফাইলের সাথে কাজ করবে।

আপনি যদি এক্সএমএল ফাইলগুলির সাথে কাজ করেন এবং আপনি একটি ট্যাগ সরাতে চান তবে দরকারী। এই উদাহরণে এটি "ইসট্যাগ" ট্যাগের প্রথম উপস্থিতিটি সরিয়ে দেয়।

COMMAND:

sed -e 0,/'<isTag>false<\/isTag>'/{s/'<isTag>false<\/isTag>'//}  -e 's/ *$//' -e  '/^$/d'  source.txt > output.txt

উত্স ফাইল (উত্স। টেক্সট)

<xml>
    <testdata>
        <canUseUpdate>true</canUseUpdate>
        <isTag>false</isTag>
        <moduleLocations>
            <module>esa_jee6</module>
            <isTag>false</isTag>
        </moduleLocations>
        <node>
            <isTag>false</isTag>
        </node>
    </testdata>
</xml>

ফলাফল ফাইল (আউটপুট.টেক্সট)

<xml>
    <testdata>
        <canUseUpdate>true</canUseUpdate>
        <moduleLocations>
            <module>esa_jee6</module>
            <isTag>false</isTag>
        </moduleLocations>
        <node>
            <isTag>false</isTag>
        </node>
    </testdata>
</xml>

PS: এটি আমার পক্ষে সোলারিস সানোএস 5.10 (বেশ পুরানো) তে কাজ করে নি, তবে এটি লিনাক্স ২. 2., সেড সংস্করণ ৪.১.৫ এ কাজ করে


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

0

নতুন কিছু নয় তবে সম্ভবত কিছুটা দৃ concrete় উত্তর: sed -rn '0,/foo(bar).*/ s%%\1%p'

উদাহরণ: xwininfo -name unity-launcherযেমন আউটপুট উত্পাদন করে:

xwininfo: Window id: 0x2200003 "unity-launcher"

  Absolute upper-left X:  -2980
  Absolute upper-left Y:  -198
  Relative upper-left X:  0
  Relative upper-left Y:  0
  Width: 2880
  Height: 98
  Depth: 24
  Visual: 0x21
  Visual Class: TrueColor
  Border width: 0
  Class: InputOutput
  Colormap: 0x20 (installed)
  Bit Gravity State: ForgetGravity
  Window Gravity State: NorthWestGravity
  Backing Store State: NotUseful
  Save Under State: no
  Map State: IsViewable
  Override Redirect State: no
  Corners:  +-2980+-198  -2980+-198  -2980-1900  +-2980-1900
  -geometry 2880x98+-2980+-198

xwininfo -name unity-launcher|sed -rn '0,/^xwininfo: Window id: (0x[0-9a-fA-F]+).*/ s%%\1%p'উত্পাদন সহ উইন্ডো আইডি বের করা :

0x2200003

0

পসিক্সলি (সেডেও বৈধ), কেবলমাত্র একটি রেগেক্স ব্যবহৃত হয়েছে, কেবল একটি লাইনের জন্য মেমরির প্রয়োজন (যথারীতি):

sed '/\(#include\).*/!b;//{h;s//\1 "newfile.h"/;G};:1;n;b1'

ব্যাখ্যা:

sed '
/\(#include\).*/!b          # Only one regex used. On lines not matching
                            # the text  `#include` **yet**,
                            # branch to end, cause the default print. Re-start.
//{                         # On first line matching previous regex.
    h                       # hold the line.
    s//\1 "newfile.h"/      # append ` "newfile.h"` to the `#include` matched.
    G                       # append a newline.
  }                         # end of replacement.
:1                          # Once **one** replacement got done (the first match)
n                           # Loop continually reading a line each time
b1                          # and printing it by default.
'                           # end of sed script.

0

ব্যবহারের ক্ষেত্রে সম্ভবত এটি হতে পারে যে আপনার উপস্থিতিগুলি আপনার ফাইল জুড়ে ছড়িয়ে রয়েছে, তবে আপনি জানেন যে কেবলমাত্র আপনার উদ্বেগ প্রথম 10, 20 বা 100 লাইনে রয়েছে।

তারপরে কেবল সেই লাইনগুলিকে সম্বোধন করা সমস্যাটিকে ঠিক করে দেয় - এমনকি ওপির শব্দের সাথে প্রথমে বিবেচনা করা হলেও।

sed '1,10s/#include/#include "newfile.h"\n#include/'

0

এখানে সম্ভাব্য সমাধান হ'ল সংকলকটিকে উত্স ফাইলগুলিতে উল্লেখ না করে শিরকটি অন্তর্ভুক্ত করতে বলা উচিত। জিসিসিতে এই বিকল্পগুলি রয়েছে:

   -include file
       Process file as if "#include "file"" appeared as the first line of
       the primary source file.  However, the first directory searched for
       file is the preprocessor's working directory instead of the
       directory containing the main source file.  If not found there, it
       is searched for in the remainder of the "#include "..."" search
       chain as normal.

       If multiple -include options are given, the files are included in
       the order they appear on the command line.

   -imacros file
       Exactly like -include, except that any output produced by scanning
       file is thrown away.  Macros it defines remain defined.  This
       allows you to acquire all the macros from a header without also
       processing its declarations.

       All files specified by -imacros are processed before all files
       specified by -include.

মাইক্রোসফ্টের সংকলকটিতে / এফআই (জোরপূর্বক অন্তর্ভুক্ত) বিকল্প রয়েছে।

প্ল্যাটফর্ম কনফিগারেশনের মতো কিছু সাধারণ শিরোনামের জন্য এই বৈশিষ্ট্যটি কার্যকর হতে পারে। লিনাক্স কার্নেলের মেকফিল এটির -includeজন্য ব্যবহার করে ।


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