ফাইলের শেষ পর্যন্ত ম্যাচের পরে সমস্ত লাইন কীভাবে মুদ্রণ করবেন?


48

ইনপুট ফাইল 1 হ'ল:

dog 123 4335
cat 13123 23424 
deer 2131 213132
bear 2313 21313

আমি ম্যাচটি অভ্যন্তরীণ থেকে প্যাটার্নটি দিই other file( dog 123 4335ফাইল 2 থেকে)।

আমি লাইনটির প্যাটার্নটি মেলে dog 123 4335এবং ম্যাচ লাইন ছাড়াই সমস্ত লাইন মুদ্রণের পরে আমার আউটপুটটি:

cat 13123 23424
deer 2131 213132
bear 2313 21313

যদি কেবল লাইনের ঠিকানা ছাড়াই কেবল প্যাটার্নটি ব্যবহার করে, উদাহরণস্বরূপ 1s লাইনগুলি কীভাবে মেলে এবং মুদ্রণ করা যায়?


অন্যান্য ফাইলগুলিতে অনুসন্ধানের জন্য কেবলমাত্র একক প্যাটার্ন, বা প্রতি লাইন একটি থাকতে পারে এবং অনুসন্ধান করা ফাইলটিতে যে লাইনটি প্রথমে পাওয়া যাবে তা অনুসন্ধান শুরু করতে পারে?
সিরো সান্তিলি 新疆 改造 中心 法轮功 六四 事件

উত্তর:


27

ধরে নিই যে আপনি আপনার প্যাটার্নের সাথে পুরো লাইনটি জিএনইউয়ের সাথে মেলে করতে চান sed, এটি কাজ করে:

sed -n '/^dog 123 4335$/ { :a; n; p; ba; }' infile

মান সমতুল্য:

sed -ne '/^dog 123 4335$/{:a' -e 'n;p;ba' -e '}' infile

নিম্নলিখিত ইনপুট সহ ( infile):

cat 13123 23424 
deer 2131 213132
bear 2313 21313
dog 123 4335
cat 13123 23424 
deer 2131 213132
bear 2313 21313

আউটপুটটি হ'ল:

cat 13123 23424 
deer 2131 213132
bear 2313 21313

ব্যাখ্যা:

  • /^dog 123 4335$/ পছন্দসই নিদর্শন জন্য অনুসন্ধান।
  • :a; n; p; ba;একটি লুপ যা ইনপুট ( n) থেকে একটি নতুন লাইন নিয়ে আসে , এটি প্রিন্ট করে ( p), এবং শাখাগুলি আবার লেবেল লেবেল করে :a; ...; ba;

হালনাগাদ

আপনার প্রয়োজনের নিকটে আসে এমন একটি উত্তর এখানে দেওয়া হয়েছে, যেমন ফাইল 2-তে প্যাটার্ন, ফাইল 1 থেকে গ্রেপিং:

tail -n +$(( 1 + $(grep -m1 -n -f file2 file1 | cut -d: -f1) )) file1

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

আপনি যদি প্রথম ম্যাচের পরিবর্তে শেষ ম্যাচ থেকে শুরু করতে চান তবে তা হ'ল:

tail -n +$(( 1 + $(grep -n -f file2 file1 | tail -n1 | cut -d: -f1) )) file1

নোট করুন যে লেজের সমস্ত সংস্করণ প্লাস-স্বরলিপি সমর্থন করে না।


এটি সেডে এন এবং পি কমান্ডগুলির প্রথম উদাহরণ যা আমি দেখেছি যে খুব বেশি দূরে সেড নেওয়ার মতো মনে হয় না। দেখে মনে হচ্ছে (আমার সংক্ষিপ্ত পরীক্ষাগুলি থেকে) যে sed -n '/^dog 123 4335$/ { :a; p; n; ba; }' infile(পি এবং এন স্যুইচ করা আছে) সাফল্যের সাথে মেলে এমন লাইনটি সফলভাবে অন্তর্ভুক্ত করে।
জোশিয়ার যোদার

26

আপনার যদি যুক্তিসঙ্গত সংক্ষিপ্ত ফাইলটি grepএকা কাজ করতে পারে:

grep -A5000 -m1 -e 'dog 123 4335' animals.txt

5000 "" যুক্তিসঙ্গতভাবে সংক্ষিপ্ত "তে আমার অনুমান, কারণ grepপ্রথম ম্যাচটি খুঁজে পাওয়া যায় এবং পরবর্তী 5000 লাইনের সাথে এটি মিলিয়ে যায় (ফাইলটির অনেকগুলি দরকার নেই)। আপনি যদি ম্যাচটি নিজেই না চান তবে আপনাকে এটি কেটে ফেলতে হবে, যেমন

grep -A5000 -m1 -e 'dog 123 4335' animals.txt | tail -n+2


আপনি যদি প্রথমটি না চান তবে ডিলিমিটার হিসাবে শেষ ম্যাচটি আপনি এটি ব্যবহার করতে পারেন:

tac animals.txt | sed -e '/dog 123 4335/q' | tac

এই লাইনটি animals.txtরেখাগুলির বিপরীত ক্রমে পড়ে এবং আউটপুটগুলি লাইনটি সহ করে dog 123 4335এবং তারপরে যথাযথ ক্রম পুনরুদ্ধার করতে আবার বিপরীত হয়।

আবার ফলস্বরূপ আপনার যদি ম্যাচের প্রয়োজন না হয় তবে লেজ যুক্ত করুন। (আপনি ছাড়ার পূর্বে এর বাফারটি ফেলে দেওয়ার জন্য সেড এক্সপ্রেশনটিকে আরও জটিল করতে পারেন))


আমার পরীক্ষার দ্বারা, GNU গ্রেপ 3.0 প্রসঙ্গের পরে (নির্দিষ্ট মান নির্বিশেষে) 132 লাইনের বেশি আউটপুট দেয় না।
রুভিম

22

অনুশীলনে আমি সম্ভবত বেশিরভাগ সময়ই এট 3 মিরার উত্তরটি ব্যবহার করতাম এবং রেখাগুলি দিয়ে নেভিগেট করতে চাইলে অ্যালেক্সির উত্তরটি দুর্দান্ত (এটিও এর সাথে কাজ করে less)। ওটো, আমি সত্যিই অন্য একটি পদ্ধতির পছন্দ করি (যা হ'ল বিপরীত গিলসের উত্তর :

sed -n '/dog 123 4335/,$p'

-nপতাকা সহ যখন ডাকা হয় তখন sedডিফল্টরূপে মুদ্রণ করে না যে লাইনগুলি আরও প্রসেস করে। তারপরে আমরা একটি 2-ঠিকানা ফর্ম ব্যবহার করি /dog 123 4335/যা ফাইলের শেষ হওয়া অবধি লাইন মেলানো থেকে কমান্ড প্রয়োগ করতে বলে (এর দ্বারা প্রতিনিধিত্ব করে $)। প্রশ্নে কমান্ডটি হ'ল p, যা বর্তমান লাইনটি মুদ্রণ করে। সুতরাং, এর অর্থ "এক মিল /dog 123 4335/থেকে শেষ অবধি সমস্ত লাইন মুদ্রণ করুন ।"


3
এটি dogলাইনটি মুদ্রণ করে যদিও এটি এখানে চান না।
স্টাফেন চেজেলাস

1
এটি দেখতে সেরা উত্তরের মতো (এবং আমার নিজের ক্ষেত্রে কাজ করে) তবে ম্যাচটি করা লাইনটি এড়িয়ে যাওয়ার জন্যও খাপ খাইয়ে নেওয়া দরকার।
পাভেল rdিমেরদা

1
সেড-এন '/ কুকুর 123 4335 /, $ পি' | সেড '1 ডি 'কুকুরের লাইনটি সরিয়ে ফেলবে
কেমিন ঝো

1
sed -n '/dog 123 4335/,$p' | tail -n +2
ম্যাচটিও

15
sed -e '1,/dog 123 4335/d' file1

যদি আপনার কোনও ফাইল থেকে প্যাটার্নটি পড়ার দরকার হয় তবে সেড কমান্ডের পরিবর্তে। যদি ফাইলটিতে একটি উপদ্রব প্যাটার্ন থাকে:

sed -e "1,/$(cat file2)/d" file1

যদি ফাইলটিতে আক্ষরিক স্ট্রিং থাকে তবে সমস্ত বিশেষ অক্ষর উদ্ধৃত করুন। আমি ধরে নিই যে ফাইলটিতে একটি লাইন রয়েছে contains

sed -e "1,/$(sed 's/[][\\\/^$.*]/\\&/g' file2)/d" file1

আপনি যদি চান যে ম্যাচটি কেবল একটি স্ট্রিং নয়, পুরো লাইন হয় তবে প্যাটার্নটি মোড়ানো ^…$

sed -e "1,/^$(sed 's/[][\\\/^$.*]/\\&/g' file2)\$/d" file1

6
প্যাটার্নটি প্রথম লাইনে থাকলে এটি কাজ করবে না। জিএনইউ sedএর 0,/dog.../dজন্য রয়েছে ।
স্টাফেন চেজেলাস

14

$ more +/"dog 123 4335" file1


4
এটি সঙ্গে কাজ করে less
ব্র্যান্ডিজি 26'15

3
টার্মিনালটিতে চালাক, তবে আপনি যদি এটির মতো অন্য কোনও কিছুতে পাইপ করেন তবে এটি আসলে কাজ করে না tac
jcomeau_ictx

আমি এটি এর মতো ব্যবহার করছি, $ আরও + / "আমার শব্দগুলি মেলে" ফাইল 1 >> ফাইল
এএমবি

1
হতে পারে পসিক্স 7 +দ্বারা প্রতিস্থাপিত হয়েছিল -p: pubs.opengroup.org/onlinepubs/9699919799/utilities/more.html তবে ইউজ -লিনাক্স ২.২০.১ এ এখনও প্রয়োগ করা হয়নি। এবং এটি মুদ্রণ করে skipping..এবং কিছু অতিরিক্ত নিউলাইনগুলি (স্ট্যাডারের কাছে আমি প্রত্যাশা করি, তাই ভাল হতে পারে)।
সিরো সান্তিলি 新疆 改造 中心 法轮功 六四 事件

তারপরে কি কিছু বদলেছে? আমার মন্তব্যটি 3 টি upvotes পেয়েছে তাই এটি সম্ভবত প্রাসঙ্গিক হতে পারে ...
jcomeau_ictx


5

উত্তেজক ব্যবহারের এক উপায়:

awk 'NR==FNR{a[$0];next}f;($0 in a){f=1}'  file2 file1

যেখানে ফাইল 2-এ আপনার অনুসন্ধানের নিদর্শন রয়েছে। প্রথমে ফাইল 2 এর সমস্ত বিষয়বস্তু অ্যারে "এ" তে সংরক্ষণ করা হয়। ফাইল 1 প্রক্রিয়া করা হয়, প্রতিটি লাইন অ্যারের বিপরীতে পরীক্ষা করা হয়, এবং উপস্থিত না থাকলে শুধুমাত্র মুদ্রিত।


আমি মনে করি ওপিতে প্রতি লাইনটি অনুসরণ করে প্রতিটি লাইন আউটপুট চায়।
থোর

@ থোর: এটি দেখানোর জন্য ধন্যবাদ, এখনই এটি আপডেট করেছে ...
গুরু

সুন্দরভাবে সম্পন্ন :).
থোর

5

যদি ইনপুটটি হ'তে দেখা যায় এমন নিয়মিত ফাইল:

জিএনইউ সহ grep:

{ grep  -xFm1 'dog 123 4335' >&2
  cat; } <infile 2>/dev/null >outfile

সাথে sed:

{ sed -n '/^dog 123 4335$/q'
  cat; } <infile >outfile

ডাব্লুgrep / -mঅপশন নামে পরিচিত একটি জিএনইউ ম্যাচটি ইনপুট ছেড়ে দেবে - এবং এটি তার শেষ ম্যাচটি খুঁজে পাওয়ার সাথে সাথে তার (lseekable) ইনপুট এফডি ছাড়বে । সুতরাং grepডাব্লু / কে -m1কোনও ফাইলের মধ্যে কোনও প্যাটার্নের প্রথম উপস্থিতি খুঁজে পাওয়া যায় catএবং স্ট্যান্ডআউটে ফাইলের মধ্যে প্যাটার্নের প্রথম ম্যাচের পরে সমস্ত কিছু লেখার জন্য ইনপুটটি ঠিকঠাক জায়গায় অফসেট করে দেয় ।

এমনকি কোনও জিএনইউ ছাড়াই grepআপনি ঠিক একই জিনিস ডাব্লু / পসিক্স সামঞ্জস্যপূর্ণ করতে পারেন sed- যখন sed qইউটিস এটি নির্দিষ্ট করে তার ইনপুটটি যেখানে ঠিক সেখানে রাখে। GNU sedএইভাবে মানদণ্ড অনুসারে নয়, তবে উপরের সম্ভবত ডাব্লু / জিএনইউ কাজ করবে sedনা আপনি যদি না এটির -uসুইচ দিয়ে কল করেন call


নোট, sedস্ট্রীম শেয়ারিং এখানে প্রদর্শিত নয় বিশেষভাবে (যদিও, হ্যাঁ, মান উল্লেখ করা বিশেষভাবে উদাহরণ আছে sedমুক্ত-ফর্ম ও শর্তসাপেক্ষে সমবায় কর্মপ্রবাহ দেখানো একটি ইউটিলিটি এইভাবে সক্ষম হিসাবে)। উল্লেখযোগ্যভাবে, সমস্ত স্ট্যান্ডার্ড ইউটিলিটিগুলি বোঝানো হয় এবং এভাবে নির্দিষ্টভাবে পরবর্তী পাঠককে কোনও প্রসেসিংয়ে ব্যর্থ না করে ইনপুট স্ট্রিমগুলির কার্সার অবস্থানগুলি সহযোগিতা এবং ভাগ করে নেওয়া হয়। grep -qএটি করা উচিত; ইনপুটটিতে grepকোনও মিল পাওয়া মাত্রই নিঃশব্দে ফিরে আসা উচিত, এবং কোনও ইনপুট বাকী, মান অনুসারে ডিফল্টরূপে গ্রহন করা উচিত নয়।
মাইকজার্ভ

4

দ্বিতীয় ফাইলে প্যাটার্নটি সংরক্ষণ না করেই বিষয়টিতে আমার প্রশ্নের উত্তর। আমার পরীক্ষার ফাইলটি এখানে:

$ cat animals.txt 
cat 13123 23424 
deer 2131 213132
bear 2313 21313
dog 123 4335
cat 13123 23424 
deer 2131 213132
bear 2313 21313

জিএনইউ সেড:

 $ sed '0,/^dog 123 4335$/d' animals.txt 
 cat 13123 23424 
 deer 2131 213132
 bear 2313 21313

পার্ল:

$ perl -ne 'print unless 1.../^dog 123 4335$/' animals.txt
cat 13123 23424 
deer 2131 213132
bear 2313 21313

কোনও ফাইলের প্যাটার্ন সহ পার্ল বৈকল্পিক:

$ cat pattern.txt 
dog 123 4335
$ perl -ne 'BEGIN{chomp($p=(<STDIN>)[0])};print unless 1../$p/;' animals.txt < pattern.txt
cat 13123 23424 
deer 2131 213132
bear 2313 21313

2

Wth ed:

ed -s file1 <<< '/dog 123 4335/+1,$p'

এটি pএখানে একটি স্ট্রিং এড করতে একটি rint কমান্ড প্রেরণ ; মুদ্রণ কমান্ডটি ম্যাচের পরে ( +1) dog 123 4335ফাইলের শেষে ( ) সীমাবদ্ধ থাকে $


1

যদি আপনি একটি অস্থায়ী ফাইল তৈরি করতে আপত্তি না দেখায় এবং csplitউপলভ্য থাকে তবে এটি কাজ করে:

sh -c 'csplit -sf"$1_" "$1" "%^$(cat "$2")%+1" && cat "${1}_00"' sh file1 file2

নোট file1হ'ল ইনপুট ফাইল এবং file2এটি প্যাটার্ন ফাইল (প্রশ্নে বর্ণিত)।

উপরের কমান্ডটির দীর্ঘ রূপটি হ'ল:

sh -c 'csplit --quiet --prefix="$1_" "$1" "%^$(cat "$2")%+1" && cat "${1}_00"' sh file1 file2

অর্থাত,

csplit --quiet --prefix="file1_" "file1" "%^$(cat "file2")%+1" && cat "file1_00"

csplitprefixউপরের পতাকা ছাড়াই ফাইলটি তৈরি করা হবে xx00(উপসর্গ xx, এবং প্রত্যয় হচ্ছে 00)। উপরের পতাকা দিয়ে এটি ফাইল তৈরি করে file1_00quietপতাকা ব্যতীত এটি আউটপুট ফাইলের আকার (ফলাফলযুক্ত ফাইলের আকার) মুদ্রণ করে।


0

যেহেতু awk স্পষ্টরূপে অনুমোদিত নয়, তাই এখানে আমার বিড়ালটিকে 'বিড়াল' বলে ধরে নিচ্ছে is

awk '$0 ~ /cat/ { vart = NR }{ arr[NR]=$0 } END { for (i = vart; i<=NR ; i++) print arr[i]  }' animals.txt

0

ফাইলের শেষ পর্যন্ত ম্যাচের পরে সমস্ত লাইন কীভাবে মুদ্রণ করবেন?

এটি রাখার আরেকটি উপায় হ'ল "কীভাবে প্রথম sedপর্ব থেকে ম্যাচ (সমস্ত) অবধি সমস্ত রেখাগুলি মুছবেন" এবং এটি লিখিত হতে পারে :

sed -e '1,/MATCH PATTERN/d'

1
একমাত্র সমস্যাটি যখন প্যাটার্নটি প্রথম লাইনে থাকে ...
don_crissti


আমার ধারণা এখানে সিদ্ধান্ত নিতে আমাদের একটি কমিটি দরকার need
পোজ

1
@ পয়েজ: নাহ, আপনি একই উত্তর কম ব্যাপকভাবে সরবরাহ করেছেন
থোর

@ ডন_ক্রিসটি, sed -e '0,/MATCH PATTERN/d'তারপরে কী হবে?
ভেলকান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.