প্যাডের উপরে প্যাটার্নের উপরে রেখার পরিসীমা মুছে ফেলুন (বা অ্যাডক)


28

আমার কাছে নিম্নলিখিত কোড রয়েছে যা প্যাটার্ন সহ bananaলাইনগুলি এবং এর পরে 2 টি লাইন মুছে ফেলবে :

sed '/banana/I,+2 d' file

এ পর্যন্ত সব ঠিকই! কিন্তু আমি এটি প্রয়োজন 2 লাইন মুছে ফেলার জন্য সামনে banana , কিন্তু আমি এটি একটি "বিয়োগ চিহ্ন" বা যাই হোক না কেন (কি অনুরূপ সঙ্গে পেতে পারে না grep -v -B2 banana fileকি করা উচিত কিন্তু না):

teresaejunior@localhost ~ > LC_ALL=C sed '-2,/banana/I d' file
sed: invalid option -- '2'
teresaejunior@localhost ~ > LC_ALL=C sed '/banana/I,-2 d' file
sed: -e expression #1, char 16: unexpected `,'
teresaejunior@localhost ~ > LC_ALL=C sed '/banana/I,2- d' file
sed: -e expression #1, char 17: unknown command: `-'

1
সবচেয়ে সহজ পদ্ধিতি হল, একটি বিন্যাস সব ডেটা লোড তারপর আউটপুট কি রয়ে যায় অবাঞ্ছিত লাইন এড়িয়ে যেতে হল: awk '{l[m=NR]=$0}/banana/{for(i=NR-2;i<=NR;i++)delete l[i]}END{for(i=1;i<=m;i++)if(i in l)print l[i]}'। এটি দক্ষ নয়, সুতরাং এটি কেবল একটি ইঙ্গিত, কোনও সমাধান নয়।
manatwork

6
শুধু কর tac file | sed ... | tac। : পি
অ্যাঙ্গাস

@angus আমি এটি সম্পর্কে ভাবি নি;)
তেরেসা ই জুনিয়র

1
আপনি এটি করতে পারেন sed '/banana/,+2d' file যে কাজ করতে পারে
আক্কস

1
যদি আপনি জঞ্জাল ব্যবহারের জন্য উন্মুক্ত হন তবে এটি খুব সহজ: awk 'tolower($0)~/bandana/{print prev[!idx];print prev[idx]} {idx=!idx;prev[idx]=$0}' filein যেহেতু এটি একটি মন্তব্য এবং উত্তর নয় (ইতিমধ্যে অন্যান্য উত্তর রয়েছে), আমি খুব বেশি বিশদে যাব না, তবে এর ক্রুসটি হ'ল আপনার কাছে সর্বদা পূর্ববর্তী দুটি রেকর্ড পূর্ব [0] এবং পূর্ববর্তী [1], "সর্বশেষতম" নির্ভর করে যা কোন পুনরাবৃত্তির উপর নির্ভর করে তবে সর্বদা থাকে prev[idx], সুতরাং যখন আপনি মুদ্রণ করবেন, আপনি !idxতখন মুদ্রণ করুন idx। নির্বিশেষে, বিকল্প idxএবং বর্তমান রেকর্ডটি ভিতরে রাখুন prev[idx]
Luv2code

উত্তর:


22

শেড ব্যাকট্র্যাক করে না: একবার লাইন প্রসেস করার পরে এটি হয়ে যায়। সুতরাং "একটি লাইন সন্ধান করুন এবং পূর্ববর্তী এন লাইনগুলি মুদ্রণ করুন" ঠিক তেমন কাজ করবে না, "লাইনটি সন্ধান করুন এবং পরবর্তী এন লাইনগুলি মুদ্রণ করুন" যা গ্রাফ্ট করা সহজ unlike

যদি ফাইলটি খুব বেশি দীর্ঘ না হয়, যেহেতু আপনি GNU এক্সটেনশানগুলির সাথে ঠিক আছেন বলে মনে হয়, আপনি tacফাইলটির লাইনগুলি বিপরীত করতে ব্যবহার করতে পারেন ।

tac | sed '/banana/I,+2 d' | tac

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

#!/bin/sh
{ "exec" "awk" "-f" "$0" "$@"; } # -*-awk-*-
# The array h contains the history of lines that are eligible for being "before" lines.
# The variable skip contains the number of lines to skip.
skip { --skip }
match($0, pattern) { skip = before + after }
NR > before && !skip { print NR h[NR-before] }
{ delete h[NR-before]; h[NR] = $0 }
END { if (!skip) {for (i=NR-before+1; i<=NR; i++) print h[i]} }

ব্যবহার: /path/to/script -v pattern='banana' -v before=2


2
sedউইন্ডো স্লাইডিংও করতে পারে, তবে ফলস্বরূপ স্ক্রিপ্টটি সাধারণত এতটা অপঠনযোগ্য যে এটি সহজেই ব্যবহার করা সহজ awk
jw013

@ গিলিস .. awkস্ক্রিপ্টটি ঠিক মতো নয়; যেমনটি এটি ফাঁকা রেখাগুলি মুদ্রণ করে এবং সর্বশেষ লাইনগুলি মিস করে। এটি এটি ঠিক করে দিয়েছে বলে মনে হচ্ছে তবে এটি নিজেই আদর্শ বা সঠিক হতে পারে না: if (NR-before in h) { print...; delete...; }... এবং ENDবিভাগে: for (i in h) print h[i]... এছাড়াও, awk স্ক্রিপ্টটি ম্যাচিংয়ের লাইনটি প্রিন্ট করে, তবে tac/secসংস্করণটি দেয় না; তবে প্রশ্নটি এই বিষয়ে কিছুটা দ্বিধাবিভক্ত .. "মূল" অ্যাজক স্ক্রিপ্ট, যার প্রতি আপনি একটি লিঙ্ক সরবরাহ করেছিলেন, তা ঠিক কাজ করে .. আমি এটি পছন্দ করি ... উপরের 'মোড' মুদ্রণের পরে কীভাবে প্রভাব ফেলবে তা আমি নিশ্চিত নই লাইন ...
পিটার.ও

@ পিটার.ও ধন্যবাদ, অ্যাডকের স্ক্রিপ্টটি আরও ভাল হওয়া উচিত। এবং এটি আমাকে –-৮ বছরেরও কম সময় নিয়েছে!
গিলস 'অসন্তুষ্ট হওয়া বন্ধ করুন'

19

প্রাক্তন বা ভিএম-ই দিয়ে এটি বেশ সহজ

    vim -e - $file <<@@@
g/banana/.-2,.d
wq
@@@

অভিব্যক্তিটি পড়ে: বর্তমান লাইন -2 থেকে বর্তমান লাইনের পরিসরে কলাযুক্ত প্রতিটি লাইনের জন্য মুছুন।

মজার বিষয়টি হ'ল রেঞ্জটি পিছনের দিকে এবং সামনের দিকে অনুসন্ধানগুলিও ধারণ করতে পারে, উদাহরণস্বরূপ এটি ফাইলের সমস্ত বিভাগ মুছে ফেলবে আপেলযুক্ত একটি লাইন দিয়ে শুরু করে এবং কমলা যুক্ত একটি লাইন দিয়ে শেষ হবে এবং কলা দিয়ে একটি লাইন থাকবে:

    vim -e - $file <<@@@
g/banana/?apple?,/orange/d
wq
@@@

7

"স্লাইডিং উইন্ডো" এতে ব্যবহার করে perl:

perl -ne 'push @lines, $_;
          splice @lines, 0, 3 if /banana/;
          print shift @lines if @lines > 2
          }{ print @lines;'

6

আপনি এটিকে মোটামুটিভাবে সহজভাবে এগুলি করতে পারেন sed:

printf %s\\n    1 2 3 4match 5match 6 \
                7match 8 9 10 11match |
sed -e'1N;$!N;/\n.*match/!P;D'

আমি জানি না কেন কেউ অন্যথায় বলবে, তবে একটি লাইন খুঁজে বের করতে এবং পূর্ববর্তী লাইনগুলি মুদ্রণেরsed জন্য অন্তর্নির্মিত রিন্ট আদিমকে অন্তর্ভুক্ত করে Pযা \nপ্যাটার্ন স্পেসে কেবল প্রথম ইলাইন চরিত্র পর্যন্ত লেখায় । পরিপূরক Dএকাদশ আদিম পুনরাবৃত্তভাবে যা অবশিষ্ট রয়েছে তা স্ক্রিপ্টটি পুনর্ব্যবহার করার আগে প্যাটার্ন স্পেসের একই বিভাগটিকে সরিয়ে দেয়। এবং এটি বন্ধ করার জন্য, Nসন্নিবেশ করা \nইওলাইন চরিত্রটি অনুসরণ করে প্যাটার্ন স্পেসে এক্সপুট ইনপুট লাইন যুক্ত করার জন্য একটি আদিম রয়েছে ।

যাতে sedআপনার প্রয়োজন মতো একটি লাইনের হওয়া উচিত। matchআপনার রিজেপ্সপ যা কিছু আছে তার সাথে আপনি কেবল প্রতিস্থাপন করুন এবং আপনি সোনালী। এটিও খুব দ্রুত সমাধান হওয়া উচিত ।

এটিও নোট করুন যে এটি পূর্বের দুটি লাইনের জন্য শান্ত আউটপুটে ট্রিগার হিসাবে matchতাত্ক্ষণিকভাবে অন্যটিকে সঠিকভাবে গণনা করবে এবং এর প্রিন্টটিও শান্ত করবে:match


1
7match
8
11match

এটি একটি স্বেচ্ছাসেবী সংখ্যক লাইনের জন্য কাজ করার জন্য , আপনাকে যা করতে হবে তা হল একটি সীসা অর্জন করা।

তাই:

    printf %s\\n     1 2 3 4 5 6 7match     \
                     8match 9match 10match  \
                     11match 12 13 14 15 16 \
                     17 18 19 20match       |
    sed -e:b -e'$!{N;2,5bb' -e\} -e'/\n.*match/!P;D'

1
11match
12
13
14
20match

... কোনও ম্যাচের আগের 5 টি লাইন মুছে ফেলে।


1

ব্যবহার man 1 ed:

str='
1
2
3
banana
4
5
6
banana
8
9
10
'

# using Bash
cat <<-'EOF' | ed -s <(echo "$str")  | sed -e '1{/^$/d;}' -e '2{/^$/d;}'
H
0i


.
,g/banana/km\
'm-2,'md
,p
q
EOF
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.