গ্রেপের- এ-বি-সি সুইচগুলির (আগে এবং পরে কয়েকটি লাইন মুদ্রণের জন্য) বিকল্প আছে কি?


10
grep -A 2 -B 3 

গ্রেপ স্ট্রিংয়ের পরে 2 টি লাইন মুদ্রণ করে এবং 3 লাইন আগে প্রিন্ট করে।

grep -C 3

3 লাইন আগে এবং 3 লাইন পরে মুদ্রণ

দুর্ভাগ্যক্রমে, grepআমি ব্যবহার করছি এই বিকল্পগুলি সমর্থন করে না। এটি অনুকরণ করার জন্য কোনও বিকল্প কমান্ড বা স্ক্রিপ্ট পাওয়া যায়? sed/ awk/ perl/ শেল স্ক্রিপ্ট ব্যবহার করছেন ?


+1 আমি জানতাম না যে সেখানে একটি -Cস্যুইচ আছে।
লেজার

1
GNU এর গ্রেপ ইনস্টল করুন। আরও সাধারণভাবে, যখন কোনও নতুন সান মেশিন এখানে উপস্থিত হয়েছিল, সেটআপের প্রথম ধাপটিই ছিল কেউ ডেকেছিল GNU > /usr/local। জিএনইউ প্রোগ্রামগুলিতে প্রচুর পরিমাণে দরকারী এক্সটেনশন রয়েছে এবং এগুলি স্বেচ্ছাসেবী সীমাবদ্ধতা এড়াতে ডিজাইন করা হয়েছে (তবে আপনি আকার এবং কখনও কখনও পারফরম্যান্সে অত্যন্ত মূল্য পরিশোধ করেন)। অনেক প্রোপাইটিরি সিস্টেমে জিএনইউ এবং অন্যান্য সরঞ্জামগুলির সাথে "অফিশিয়াল" প্যাকেজ সংগ্রহস্থল রয়েছে। "অংশীদার" আপনাকে তাদের সম্পর্কে বলবে না, এমনকি যখন তারা বিক্রেতা দ্বারা পরিচালিত হয় ...
ভনব্র্যান্ড

উত্তর:


6

এটি করার একটি মাঝারি কদর্য উপায়

grep -v pattern file >file.tmp; diff -c file.tmp file

বা প্রতিস্থাপন -cসঙ্গে -C NUMজন্য NUMপ্রসঙ্গের লাইন। এটি অতিরিক্ত আউটপুট উত্পাদন করবে, যদিও। (যদি আপনার diffসমর্থন করে -u/ -U NUM, এটি পরিষ্কার হয়ে যাবে))

যদি তোমার diff নেই -c/ -C/ -u, এখনও এটা করতে উপায় আছে, কিন্তু তারা প্রশংসনীয় কুশ্রী করছি। অন্যদিকে, এমন একটি সিস্টেম যা diffএমনকি সমর্থন -cকরে না তাদের সম্ভবত পার্লও নেই।


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

আপনি স্টিডিনকে আলাদা করতে পাঠাতে পারেন এবং অস্থায়ীটি এড়িয়ে যেতে পারেন:grep -v pattern file | diff -c - file
ক্যাসকেবেল

5

ACK শুধুমাত্র পার্ল প্রয়োজন আছে এবং অন্তর্ভুক্ত -A, -Bএবং -Cবিকল্প, grep মত হবে। এটি গ্রেপের পরিবর্তে পার্লের রেজেক্স সিনট্যাক্স ব্যবহার করে এবং এটি অনুসন্ধান করার জন্য ফাইলগুলি যেভাবে নির্বাচন করে তা বেশ আলাদা different আপনি -fএটি ব্যবহার করার সময় বিকল্পটি চেষ্টা করতে চাইতে পারেন (যা আসলে কোনও কিছু অনুসন্ধান না করে এটি অনুসন্ধান করবে এমন ফাইলগুলি মুদ্রণ করে)।

এটি একটি একক স্ক্রিপ্ট হিসাবে ইনস্টল করা যেতে পারে যার জন্য কোনও নন-কোর মডিউল প্রয়োজন। কেবল এটি আপনার ~/binডিরেক্টরিতে ফেলে দিন (বা আপনার পাঠের যে কোনও জায়গায় আপনার লেখার অ্যাক্সেস রয়েছে) এবং নিশ্চিত হয়ে নিন যে এটি chmodনির্বাহযোগ্য ut


এর প্রযোজনা বাক্স এবং দুর্ভাগ্যক্রমে আমার কাছে কিছু ইনস্টল করার যথেষ্ট সুযোগ নেই, এবং আমি এটি ঝুঁকি নিতে পারি না, যদিও এই পরামর্শের জন্য ধন্যবাদ আমি এটি ইনস্টল করব এবং আমার হোম ল্যাপটপে চেষ্টা করব
প্রশান্ত ভাতে

@ প্রশান্ত, ackআপনার নিজের ব্যবহারের জন্য ইনস্টল করতে আপনার মূলের দরকার নেই ।
সিজেএম

হ্যাঁ তবে এখনও আমি সেখানে এটি ব্যবহার করতে পারছি না, যদিও এটি নিশ্চিত যে এই লিপিটি আমার bin / বিনে চিরকাল থাকবে:
প্রশান্ত ভাতে

@ প্রশান্ত: আপনি কেন এটি ব্যবহার করতে পারবেন না? এটি কেবল পার্ল স্ক্রিপ্ট।
অনুপ্রেরণা

1
এটির প্রোডাকশন বাক্সে, ব্লে ব্লে ব্লাকে বিশেষ অনুমোদনের অনুমোদন নেওয়া দরকার ... এতে কোনও কিছু করতে হবে। এবং আমার মাথায় কিছু ভুল হয়ে যায়;) এবং এটির পক্ষে লাভ নেই :)
প্রশান্ত ভাতে

5

এই সহজ পার্ল স্ক্রিপ্ট grep -Aকিছুটা হলেও অনুকরণ করে

#!/usr/bin/perl

$pattern=shift; #patthern to search
$lines=shift; # number of lines to print

$n = 0;
while (<>) {
  $n = $lines if /$pattern/; # reset counting
  if ($n) { print; $n-- } # print if within
  $n = 0 if eof; # don't leak across file boundaries
}

নোট করুন যে আপনি স্ক্রিপ্টটি পাঠযোগ্য ও ব্যবহারযোগ্য করে তোলার জন্য একটি ব্যবহারের বিবৃতি যুক্ত করতে পারেন;)

USAGE:    $./grep-A.pl <pattern> <numLines> <filename> 

ভাল, পার্লের কোন সংস্করণটি এটি চালানোর দরকার আছে?
প্রশান্ত ভাতে

আমি v5.10.1 ব্যবহার করি, আমার ধারণা পার্ল 5 আজকাল মোটামুটি সাধারণ common
বিজয় অনন্ত

হ্যাঁ এর 8.৮.৮ এবং এটি কার্যকর, দুর্দান্ত, তবে আমার একটি স্ক্রিপ্ট দরকার যা বি-করুক
প্রশান্ত ভাতে

ভাল. আমি যুক্তির ক্রমটি স্যুইচ করব, যদিও; grep-A 3 fooতুলনায় অনেক বেশি প্রাকৃতিক দেখায় grep-A foo 3। :-)
ম্যাসিফিল

3

আপনি কেবল জিএনইউ গ্রেপ বা আক্ক ইনস্টল করতে পারেন (পার্লে লিখিত, জিএনইউ গ্রেপের অনেকগুলি বিকল্প এবং আরও অনেক কিছু বোঝে)।

আপনি যদি স্ট্যান্ডার্ড সরঞ্জামের সাথে কিছুটা স্ক্রিপ্টিংকে আটকে থাকতে পছন্দ করেন, তবে এখানে একটি জিন স্ক্রিপ্ট রয়েছে যা GNU গ্রেপের -Aএবং -Bবিকল্পগুলির আচরণ অনুকরণ করে । ন্যূনতম পরীক্ষিত।

#!/bin/sh
# grep-ac: a grep-like awk script
# Arguments: pattern = awk regexp to search for
#            before = number of lines to print before a match
#            after = number of lines to print after a match
{ "exec" "awk" "-f" "$0" "$@"; }
# The array h contains the history of lines that haven't been printed
# but are eligible for being "before" lines.
# The variable until contains the number of the last "after" line to print.
match($0, pattern) {   # the current line matches
    for (i in h) {
        print h[i];    # print each remaining before line
        delete h[i];   # delete each line as it's printed
    }
    until=NR+after;    # record the last after line to print
}
{
    if (NR<=until) print $0;    # from a match to its last after line: print
    else h[NR]=$0;              # after that: save in history
    delete h[NR-before];        # remove line too old to be a before line
}
END {exit !until}               # exit status: 0 if there was a match, else 1

এটি অনুসন্ধান করার ধাঁচটিgrep-ac -vpattern=PATTERN -vbefore=NBEFORE -vafter=NAFTER কোথায় PATTERNরয়েছে ( কয়েকটি বিশদ সংযোজনগুলির সাথে বর্ধিত নিয়মিত প্রকাশ ) এবং এটি ম্যাচের আগে এবং পরে যথাক্রমে মুদ্রণের জন্য কয়েকটি লাইন সংখ্যা (0 তে ডিফল্ট হবে)। উদাহরণ:NBEFORENAFTER

<input_file grep-ac -vbefore=2 -vpattern='foo *bar'

অ্যারেতে ডেটা সংরক্ষণ করে এমন কোনও সমাধান প্রশ্নের বাইরে নয় ... যেমনটি আমি আগেই উল্লেখ করেছি ফাইলাইজাইজটি বেশ বিশাল এবং এটি প্রবাহিত হতে পারে। এছাড়াও এই সিস্টেমে অ্যাড করা ফাইলের আকার 3000 বাইটের বেশি অনুমোদন করে না।
প্রশান্ত ভাতে

2
@ প্রশান্ত: আপনার আপত্তি আমি বুঝতে পারছি না। এই স্ক্রিপ্টটি একবার লাইনের আগে অযোগ্য হয়ে গেলে লাইনগুলি মুছে দেয়। এটি প্রয়োজনীয়তাগুলির সাথে অন্তর্নিহিতভাবে প্রয়োজনীয় প্রয়োজনের চেয়ে বেশি মেমরি ব্যবহার করে না, কেবলমাত্র বিশেষ উদ্দেশ্যমূলক প্রোগ্রামের চেয়ে বিশ্রীর উচ্চতর ওভারহেড থাকতে পারে (তবে পার্লের চেয়ে কম, যা আপনি বিবেচনা করছেন)। ফাইলের মোট আকার সম্পূর্ণ অপ্রাসঙ্গিক।
গিলস 'দুষ্ট হওয়া বন্ধ করুন'

2
{ "exec" "awk" "-f" "$0" "$@"; }: শেবাং-লাইন পার্সিংয়ের সীমাবদ্ধতার সীমা অতিক্রম করার খুব নিখরচায় উপায়।
সন্দেহভাজন জিম

2

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

নিম্নলিখিত অনুমানের সাথে ঘুরে দেখার সময় আমি এটি উপলব্ধি করেছি:

perl -pe 'if(/search_term/) {print foreach @A; print ">"; $B=4}; shift @A if push(@A, $_)>7; $_ = "" unless ($B-- > 0);' target_file

এটি প্রথম অনুচ্ছেদে বর্ণিত ক্যাভিয়েট সহ গ্রেপ -A7-বি 3 হিসাবে মোটামুটিভাবে সঠিকভাবে কাজ করবে।

এই ইস্যুটির একটি বিকল্প (একক ফাইলও) সমাধান হ'ল একটি কমান্ড স্ট্রিং সেড খাওয়ানোর জন্য পার্ল ব্যবহার করা:

sed -n `perl -pe '$_=(/search_term/?sprintf("%d,%dp;", $.-3,$.+4):"")' file` file

বেশ দৈর্ঘ্য অনেলাইনার, কিন্তু, এই ফাইলটি খুব বিশাল, সুতরাং এই ক্ষেত্রে লাইনগুলিকে অ্যারেতে ঠেকানো একটি খারাপ ধারণা, তাই না?
প্রশান্ত ভাতে

shift @A if push(@A,$_)>7;বিট শুধুমাত্র সর্বাধিক মাপ 7 কাছাকাছি একটি অ্যারের রাখে। (এটি আপনার -A প্যারামিটার)। দ্বিতীয় বিকল্পটি একটি অবিশ্বাস্যভাবে ছোট ফাইলকে চারপাশে রাখে (কেবল সেখানে কী উত্পন্ন হয় তা দেখার জন্য কেবল বাহ্যিক স্তর ছাড়াই পারল চালান), তবে এটি ফাইলটি দুটিবার পড়তে পারে।
ব্যবহারকারী 455

0

sedআপনি ব্যবহার করে প্রথমে কোনও whileলুপের সাথে মিলিত রেখাগুলির লাইন সংখ্যা, হ্রাস এবং বর্ধিত রেখার সংখ্যা sed -n "n1,n2p"পেতে পারেন এবং তারপরে শীর্ষস্থানীয় ( n1) এবং পিছনের ( n2) প্রসঙ্গে লাইন প্রিন্ট করতে ব্যবহার করতে পারেন (ব্যবহারকারীর sedপ্রস্তাবিত বিকল্পের অনুরূপ 45) অনেকগুলি পঠন প্রক্রিয়া যদিও পারফরম্যান্স হিট করতে পারে।

edম্যাচড লাইনের পূর্ববর্তী এবং নিম্নলিখিত লাইনগুলিকে সরাসরি উল্লেখ করতে পারে, তবে নির্দিষ্ট রেখার সীমাটি উপস্থিত না থাকলে ব্যর্থ হয়; উদাহরণস্বরূপ, ম্যাচিং লাইনটি লাইন নম্বর 2, তবে 5 প্রাক-ম্যাচ লাইনগুলি মুদ্রণ করা উচিত। ব্যবহার edতাই এটা (খালি) শুরুতে এবং শেষে লাইনের একটি যথাযথ নম্বর যোগ করা প্রয়োজন। (বিশাল ফাইলগুলির জন্য edযদিও সঠিক সরঞ্জাম নাও হতে পারে, দেখুন: বিএফএস - বড় ফাইল স্ক্যানার )।

# sample code to match lines with number 5 plus previous & following line
# (using Bash)
printf '%s\n' {1..20} > num.txt

# sed
sed -n '/5/=' num.txt | while read num; do
   n1=$((num - 1))
   n2=$((num + 1))
   [[ $n1 -lt 1 ]] && n1=1
   sed -n "${n1},${n2}p" num.txt
   echo --
done | sed -e '${/^--$/d;}'

# ed
cat <<-'EOF' | ed -s num.txt | sed -e $'N;N;a\\\n--' | sed -e '${/^--$/d;}'
H
0i
beginning: added line one
.
$a
end: added line one
.
,g/5/km\
'm-1,'m+1p
q
EOF
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.