সেড বা অ্যাজক: একটি প্যাটার্ন অনুসরণ করে এন লাইনগুলি মুছুন


105

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

উত্তর:


185

আমি এই একবার যেতে হবে।

কোনও প্যাটার্নের পরে 5 টি লাইন মুছতে (প্যাটার্নটির সাথে রেখাটি সহ):

sed -e '/pattern/,+5d' file.txt

কোনও প্যাটার্নের পরে 5 লাইন মুছতে (প্যাটার্নটির সাথে রেখাটি বাদ দিয়ে):

sed -e '/pattern/{n;N;N;N;N;d}' file.txt

14
নোট করুন যে +Nপ্যাটার্নটি একটি জিএনইউ এক্সটেনশন। প্রথম পরিবর্তন nএকটি থেকে Nএটা প্যাটার্ন সঙ্গে সঙ্গতিপূর্ণ অন্তর্ভুক্ত করার জন্য আপনার দ্বিতীয় উদাহরণে।
পরবর্তী বিজ্ঞপ্তি না দেওয়া পর্যন্ত বিরতি দেওয়া হয়েছে।

2
প্যাটার্নটি মিলে যাওয়ার পরে কীভাবে সমস্ত লাইন মুছবেন? আমি সেড-ই '/ <! - # সামগ্রী শেষ -> </div> /, $ d' আউট.txt ব্যবহার করছি তবে এতে ত্রুটিটি পাওয়া যায়: সেড: -e এক্সপ্রেশন # 1, চর 24: অতিরিক্ত অক্ষর পরে কমান্ড অগ্রিম ধন্যবাদ।
এন মোল

8
যা ঘটছে তা একই ক্ষেত্রে তবে প্রতিটি ক্ষেত্রে কিছুটা আলাদা। প্রথম রেসিপিতে /pattern/,+5একটি ব্যাপ্তি নির্ধারণ করে যা "প্যাটার্ন" ( /pattern/) সহ একটি লাইন দিয়ে শুরু হয় এবং 5 লাইন পরে ( +5) শেষ হয়। শেষ অক্ষরটি dসেই রেঞ্জের প্রতিটি লাইনে চালানোর জন্য একটি আদেশ, যা "মুছুন"। দ্বিতীয় রেসিপিতে, কোনও ব্যাপ্তির সাথে মেলে না গিয়ে এটি প্যাটার্ন ( /pattern/) সমেত লাইনটিতে মেলে এবং তারপরে একটি কমান্ডের একটি সিরিজ চালায়: {n;N;N;N;N;d}যা মূলত পরের লাইনটি মুদ্রণ করে n) এবং তারপরে পরবর্তী 4 টি লাইন পড়ে এবং শেষ করে দেয় ( N;N;N;N;d)।
পিমলটক

18
ম্যাক / ওএস এক্স সিস্টেমে আপনাকে বন্ধ করার বন্ধনীটির আগে একটি সেমিকোলন যুক্ত করতে হবে:sed -e '/pattern/{n;N;N;N;N;d;}' file.txt
এভিএল

1
সম্পূর্ণতার জন্য: করতে একটি নির্দিষ্ট প্যাটার্ন নিম্নলিখিত সব লাইন মুছে ফেলতে something করুন: sed -E '/^something$/,$d'যেখানে -EPOSIX বহনযোগ্যতা বাড়ানো Regex হয়।
not2qubit

7

জিএনইউ এক্সটেনশন ছাড়াই (যেমন ম্যাকোএসে):

কোনও প্যাটার্নের পরে 5 লাইন মুছতে (প্যাটার্ন সহ লাইনটি সহ)

 sed -e '/pattern/{N;N;N;N;d;}'

যোগ -i ''ইন-জায়গা সম্পাদনায় যান।


6

সহজ awkসমাধান:

অনুমান করুন যে মিলে যাওয়া লাইনগুলি সন্ধানের জন্য ব্যবহার করার জন্য নিয়মিত প্রকাশটি শেল ভেরিয়েবলে সঞ্চিত রয়েছে $regexএবং এতে এড়াতে লাইনের গণনা $count

তাহলে ম্যাচিং লাইন উচিত এছাড়াও এড়ানো হবে ( $count + 1লাইন এড়ানো হয়েছে হয়):

... | awk -v regex="$regex" -v count="$count" \
  '$0 ~ regex { skip=count; next } --skip >= 0 { next } 1'

যদি ম্যাচিং লাইনটি এড়ানো না যায় ( ম্যাচ বাদ দেওয়ার পরে$count লাইনগুলি ):

... | awk -v regex="$regex" -v count="$count" \
  '$0 ~ regex { skip=count; print; next } --skip >= 0 { next } 1'

ব্যাখ্যা:

  • -v regex="$regex" -v count="$count"একই নামের শেল ভেরিয়েবলের awkউপর ভিত্তি করে ভেরিয়েবলগুলি সংজ্ঞায়িত করে ।
  • $0 ~ regex আগ্রহের লাইনের সাথে মেলে
    • { skip=count; next }স্কিপ গণনাটি আরম্ভ করে এবং পরবর্তী লাইনে এগিয়ে যায়, কার্যকরভাবে ম্যাচিং লাইনটি এড়ানো যায়; 2nd দ্রবণে, printসামনে nextনিশ্চিত করে যে এটা হয় না এড়ানো।
    • --skip >= 0 এড়িয়ে যাওয়া গণনা হ্রাস করে এবং যদি এটি (এখনও)> = 0 হয় তবে পদক্ষেপ নেয়, বোঝায় যে হাতের লাইনটি এড়াতে হবে।
    • { next } পরবর্তী লাইনে এগিয়ে কার্যকরভাবে বর্তমান লাইন এড়ানো
  • 1এর জন্য সাধারণত ব্যবহৃত শর্টহ্যান্ড { print }; যে, বর্তমান লাইন সহজভাবে মুদ্রিত হয়
    • এই কমান্ডটিতে কেবল মিল না-করা এবং বাদ দেওয়া লাইনই পৌঁছায়।
    • এর 1সমতুল্য কারণটি এটি বুলিয়ান প্যাটার্ন হিসাবে ব্যাখ্যা করা { print }হয় যা 1সংজ্ঞার মাধ্যমে সর্বদা সত্যের কাছে মূল্যায়ন করে যার অর্থ এর সাথে সম্পর্কিত ক্রিয়া (ব্লক) নিঃশর্ত কার্যকর করা হয়। যেহেতু এই ক্ষেত্রে কোনও সম্পর্কিত পদক্ষেপ নেই , তাই লাইনটি মুদ্রণের ক্ষেত্রে awkডিফল্ট ।

3

এটি আপনার পক্ষে কাজ করতে পারে:

cat <<! >pattern_number.txt
> 5 3
> 10 1
> 15 5
> !
sed 's|\(\S*\) \(\S*\)|/\1/,+\2{//!d}|' pattern_number.txt |
sed -f - <(seq 21)
1 
2
3
4
5
9
10
12
13
14
15
21

10
বাহ, এটা রহস্যজনক।
পিমলটক

3
একটি চতুর (যদিও জিএনইউ-শেড-নির্দিষ্ট) সমাধান, তবে আপনি কোনও ব্যাখ্যা যোগ না করলে অল্প লোকই এতে উপকৃত হবে। pattern_number.txt1 ম কলামে মেলে ধরার প্যাটার্নযুক্ত 2-কলামের ফাইল এবং ২ য় স্থানে এড়িয়ে যাওয়ার জন্য লাইনগুলির সংখ্যা। প্রথম sedকমান্ডটি ফাইলটিকে একটি sedস্ক্রিপ্টে রূপান্তর করে যা সংশ্লিষ্ট মিল এবং স্কিপিং সম্পাদন করে; এই স্ক্রিপ্টটি দ্বিতীয় কমান্ডের মাধ্যমে -fস্ট্যান্ডিন ( -) সরবরাহ করা হয়েছে sed। ২ য় sedকমান্ড seq 21প্রদর্শন করে যে এটি কাজ করে তা আউটপুট থেকে গঠিত একটি নমুনা অ্যাডহক ইনপুট ফাইলের উপর কাজ করে।
mklement0

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

এটি সেডের একটি চিত্তাকর্ষক ব্যবহার।
ট্র্যাভিস রডম্যান

3

পার্ল ব্যবহার করা

$ cat delete_5lines.txt
1
2
3
4
5 hello
6
7
8
9
10
11 hai
$ perl -ne ' BEGIN{$y=1} $y=$.  if /hello/ ; print if $y==1 or $.-$y > 5 ' delete_5lines.txt
1
2
3
4
11 hai
$

2

এই সমাধানটি আপনাকে প্যারামিটার হিসাবে "এন" পাস করার অনুমতি দেয় এবং এটি কোনও ফাইল থেকে আপনার নিদর্শনগুলি পড়বে:

awk -v n=5 '
    NR == FNR {pattern[$0]; next}
    {
        for (patt in pattern) {
            if ($0 ~ patt) {
                print # remove if you want to exclude a matched line
                for (i=0; i<n; i++) getline
                next
            }
        }
        print
    }
' file.with.patterns -

"-" নামের ফাইলটির অর্থ স্ট্রিনটি অ্যাডকের জন্য, সুতরাং এটি আপনার পাইপলাইনের জন্য উপযুক্ত


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