নির্দিষ্ট স্ট্রিং এবং নিম্নলিখিত লাইনযুক্ত লাইন সরান


70

আমি এই ব্যবহার

cat foo.txt | sed '/bar/d'

barফাইলটিতে স্ট্রিং যুক্ত লাইনগুলি সরাতে ।

আমি তবে চাইলে সরাসরি তার পরে এই লাইনগুলি এবং লাইনটি সরিয়ে দেওয়া উচিত । বাঞ্ছনীয় মধ্যে sed, awkবা অন্যান্য সরঞ্জাম যা MinGW32 মধ্যে উপলব্ধ।

এটা কি আমি পেতে পারেন এর বিপরীত এক ধরনের grepসঙ্গে -Aএবং -Bসামনে লাইন মিলে সেইসাথে লাইন প্রিন্ট করতে / মিলেছে লাইন পরে।

এটি অর্জন করার কোন সহজ উপায় আছে?


2
কেবল তথ্যের জন্য: আমি লগগুলি বিশ্লেষণ করছি যাতে প্রবেশদ্বারগুলি দ্বি-লাইনার। সুতরাং আমি প্যাটার্নটির সাথে মিলে একটি এন্ট্রি খুঁজতে চাই এবং এটি পরবর্তী লাইনের পাশাপাশি মুছে ফেলতে চাই। অতএব আমার একটানা ম্যাচের লাইনগুলি হ্যান্ডেল করার দরকার নেই, তবে যাইহোক আপনার উত্তরগুলির সম্পূর্ণতার জন্য ধন্যবাদ!
jakub.g

উত্তর:


74

আপনার যদি জিএনইউ সেড থাকে (তাই এম্বেডেড লিনাক্স বা সাইগউইন):

sed '/bar/,+1 d'

আপনার যদি barটানা দুটি লাইনে থাকে তবে এটি দ্বিতীয় লাইনটিকে বিশ্লেষণ না করে মুছে ফেলবে। উদাহরণস্বরূপ, আপনার কাছে যদি 3-লাইন ফাইল bar/ bar/ থাকে fooতবে fooলাইনটি থাকবে।


1
দৈর্ঘ্যের জন্য +1 :) আমার বিশেষ উদাহরণে আমার ক্রমাগত barগুলি নেই তাই এটি মনে রাখা অত্যন্ত সহজ।
jakub.g

11
sed '/bar/d'আপনাকে কেবল সেই "লাইনের নির্দিষ্ট স্ট্রিং সম্বলিত সরান" করতে চান তাহলে না পরবর্তী।
এজেপি

আমি যদি গণিতের পরে সব লাইন মুছে ফেলতে চাই?
পান্ড্যা

1
@ পান্ড্য এটি ভিন্ন। আপনি উদাহরণস্বরূপ ব্যবহার করতে পারেনsed '/math/q'
গিলস

1
@ কে আপনি যদি কেবল ম্যাচের লাইনটি মুছতে চান তবে এটি আরও সহজ:sed '/bar/d'
গিলস

16

যদি barএকটানা লাইনে ঘটে থাকে তবে আপনি এটি করতে পারেন:

awk '/bar/{n=2}; n {n--; next}; 1' < infile > outfile

যা উপরের দুটি পরিবর্তন করে 2 টিরও বেশি লাইন মুছে ফেলার জন্য অভিযোজিত হতে পারে যা মিলে যাওয়াটি সহ মুছে ফেলতে পারে।

যদি না হয়, এটা সহজেই সম্পন্ন sedসঙ্গে @MichaelRollins 'সমাধান বা:

sed '/bar/,/^/d' < infile > outfile

Awk দ্রবণে অন্যান্য প্লাস আমি প্রতিস্থাপন করতে পারেন হয় /bar/সঙ্গে /bar|baz|whatever/। ইন sedযে সিনট্যাক্স কাজ করতে মনে হচ্ছে না।
jakub.g

@ জাকুব, আমার জিএনইউ সিড আছে (এখন v4.4)। অন্যদের সম্পর্কে নিশ্চিত নয়। আমি জানি যে এটি ডিফল্টরূপে "বেসিক" নিয়মিত প্রকাশের বাক্য গঠন ব্যবহার করে তাই আপনার উদাহরণটি কাজ করে না। আপনি যা চান তা অর্জন করতে আপনি প্রতিটি উল্লম্ব লাইনের সামনে একটি ব্যাকস্ল্যাশ রাখতে পারেন বা আপনি sed"বর্ধিত" নিয়মিত এক্সপ্রেশন ব্যবহার করতে চাইতে পারেন। এখানে আরও তথ্য: gnu.org/software/sed/manual/html_node/… । দয়া করে মনে রাখবেন এটিও প্রযোজ্য grep। এখানে আমার নিজের কাজ উদাহরণ আছে: echo $'0a\n1b\n2c' | sed '/0a\|1b/d'
ভিক্টর ইয়ারেমা

12

আমি সিডে সাবলীল নই, তবে অজানাতে এটি করা সহজ:

awk '/bar/{getline;next} 1' foo.txt 

অজ স্ক্রিপ্টটি পড়ে: বারযুক্ত একটি লাইনের জন্য, পরবর্তী লাইনটি (গেটলাইন) পান, তারপরে পরবর্তী সমস্ত প্রক্রিয়াজাতকরণ (পরবর্তী) এড়িয়ে যান। শেষে 1 প্যাটার্নটি বাকী রেখাগুলি মুদ্রণ করে।

হালনাগাদ

মন্তব্যে ইঙ্গিত হিসাবে, উপরোক্ত সমাধানটি ধারাবাহিকভাবে কার্যকর হয়নি bar। এখানে একটি সংশোধিত সমাধান দেওয়া হয়েছে, যা এটি বিবেচনায় নিয়েছে:

awk '/bar/ {while (/bar/ && getline>0) ; next} 1' foo.txt 

আমরা এখন সমস্ত / বার / লাইন এড়িয়ে চলতে পড়তে থাকি।


1
grep -A১০০% প্রতিলিপি তৈরি করতে , আপনাকে পরপর যে কোনও barলাইনও সঠিকভাবে পরিচালনা করতে হবে (পুরো ব্লকটি সরিয়ে এবং এর পরে 1 লাইন)।
jw013

7

এটি সম্পাদন করার জন্য আপনি সেডের স্ক্রিপ্টিং ক্ষমতাগুলি ব্যবহার করতে চাইবেন।

$ sed -e '/bar/ { 
 $!N
 d
 }' sample1.txt

নমুনা তথ্য:

$ cat sample1.txt 
foo
bar
biz
baz
buz

"এন" কমান্ডটি প্যাটার্ন স্পেসে পরবর্তী লাইন ইনপুট যুক্ত করে। এটি প্যাটার্ন ম্যাচ (/ বার /) থেকে রেখার সাথে মিলিত আপনি যে লাইনগুলি মুছতে চান তা হবে। তারপরে আপনি "d" কমান্ড দিয়ে সাধারণভাবে মুছতে পারেন।


আমি কীভাবে কনসোলে একটি নতুন লাইন টাইপ করব? নাকি এটি কেবল স্ক্রিপ্ট?
jakub.g

@ জাকুব। জিএনইউ সেড সহ:sed -e '/bar/{N;d}' sample1.txt
সাইরাস

2

যদি কোনও ম্যাচের সাথে সাথে অনুসরণ করা কোনও লাইন অপসারণ করা উচিত তবে আপনার sedপ্রোগ্রামটি পরপর ম্যাচগুলি বিবেচনা করতে হবে। অন্য কথায়, যদি আপনি কোনও ম্যাচের পরেও মিলে যায় এমন একটি লাইন সরিয়ে ফেলেন, তবে সম্ভবত আপনাকে নিম্নলিখিতটি সরিয়ে ফেলতে হবে।

এটি কেবলমাত্র যথেষ্ট কার্যকর করা হয়েছে - তবে আপনাকে কিছুটা পিছনে দেখতে হবে।

printf %s\\n     0 match 2 match match \
                 5 6 match match match \
                 10 11 12 match 14 15  |
sed -ne'x;/match/!{g;//!p;}'

0
6
11
12
15

এটি প্রতিটি পঠিত লাইনের জন্য হোল্ড এবং প্যাটার্ন স্পেসগুলি অদলবদল করে কাজ করে - যাতে শেষ লাইনের সাথে প্রতিবারের সাথে তুলনা করা যায়। সুতরাং যখন sedএকটি লাইন পড়েন তখন এটি তার বাফারগুলির বিষয়বস্তুগুলি বিনিময় করে - এবং পূর্ববর্তী লাইনটি তার সম্পাদনা বাফারের সামগ্রীগুলি হয়, যখন বর্তমান লাইনটি ধরে রাখা যায়।

সুতরাং sedএকটি মিলের জন্য পূর্ববর্তী লাইনটি পরীক্ষা করে matchএবং যদি এটি !না পাওয়া যায় তবে {ফাংশনে দুটি এক্সপ্রেশন }চালানো হয়। প্যাটার্ন স্পেসটি ওভাররাইট করে হোল্ড স্পেসটি এট sedকরবে g- যার অর্থ বর্তমান লাইনটি তারপরে হোল্ড এবং প্যাটার্ন উভয় জায়গাতেই থাকবে - এবং তারপরে এটি //তার সাম্প্রতিক সংকলিত নিয়মিত অভিব্যক্তির সাথে মিলের জন্য এটি পরীক্ষা করবে - match- এবং যদি এটি এটি না করে matchতবে হয় printed।

এর অর্থ একটি লাইন কেবল তখনই মুদ্রিত হয় যদি তা না হয় এবং তত্ক্ষণাত্ পূর্ববর্তী লাইনটি না ঘটে । এটি এস এর সিকোয়েন্সগুলির জন্য কোনও অপ্রয়োজনীয় অদলবদলকেও পূর্বসূর করে ।match matchmatch

আপনি যদি এমন একটি সংস্করণ চান যা একটি স্বেচ্ছাসেবীর সংখ্যক লাইনের পরে matchপড়তে পারে তবে এর জন্য আরও কিছুটা কাজের প্রয়োজন হবে:

printf %s\\n    1 2 3 4 match  \
                match match 8  \
                9 10 11 12 13  \
                14 match match \
                17 18 19 20 21 |
sed -net -e'/match/{h;n;//h;//!H;G;s/\n/&/5;D;}' -ep

... 5 টি প্রতিস্থাপন করুন এমন লাইনের সংখ্যার সাথে (ম্যাচযুক্ত লাইন সহ) যা আপনি মুছে ফেলতে চান ...


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