ফাইল 2 থেকে লাইনের সঠিক ফাইল (ফাইল 1 এর সামগ্রী) গ্রেপ করুন


9

আমার দুটি ফাইল আছে, file1এবং file2

এর নমুনা সামগ্রী file1হ'ল:

A B
C D
E F
G H

এবং এর সামগ্রীটি file2হ'ল:

A B
few other lines
E F
few more other lines
A B
C D
E F
G H
few more other lines
G H

সুতরাং আমি file1সামগ্রীতে সম্পূর্ণ ব্লকটি অনুসন্ধান করতে চাই file2। এর অর্থ আউটপুটে কেবল এই লাইন থাকা উচিত:

A B
C D
E F
G H

দয়া করে নোট করুন: - কেবল যে লাইনগুলি একত্রিত হচ্ছে, আউটপুট অংশ হওয়া উচিত।


আমি আপনার প্রশ্ন পাই না। আপনি যদি কেবলমাত্র সঠিক সামগ্রী file1এবং অন্য কিছু মুদ্রণ করতে চান তবে কেবল ব্যবহার করুন cat file1
ওয়াইল্ডকার্ড

@ উইল্ডকার্ড তিনি দেখতে চান যে ফাইল 2-তে ফাইল 1-এর মতো একই সামগ্রী রয়েছে কিনা। এটিকে নিয়ে ভাবুন যেন কোনও বইয়ের একটি নির্দিষ্ট অধ্যায়ের সন্ধান করছেন
সের্গেই কোলডিয়াজহনি

আমি "সেট সদস্য" একাধিক লাইনের সমন্বয়ে তৈরি হওয়ার কারণে এটি পুনরায় খুলতে ভোট দিচ্ছি (আমি প্রথমে এটি লক্ষ্য করিনি), যা প্রস্তাবিত সদৃশ প্রশ্নের উত্তর গৃহীত উত্তর দ্বারা পরিচালিত একক লাইনের চেয়ে কিছুটা জটিল।
কুসালানন্দ

1
এটি সেট সম্পর্কে নয় । আপনি যদি এটিটিকে সদৃশ হিসাবে চিহ্নিত করতে চান তবে কমপক্ষে মাল্টি-লাইন রিজেক্সপস সম্পর্কে আরও একটি প্রশ্ন সন্ধান করুন।
মাইকেল Vehrs

উত্তর:


11

grepমাল্টিলাইন প্যাটার্নের ক্ষেত্রে এটি বেশ বোকা, তবে এটিকে ঠিক করার সাথে তুলনা করার আগে \nNUL অক্ষরগুলিতে অনুসন্ধান করার জন্য প্যাটার্ন এবং পাঠ্য উভয়ের সমস্ত নতুনরেখানের অনুবাদ করা \0\0পুনরায় আউটপুটটিতে অনুবাদ \nকরা অবশ্যই স্পষ্টতই প্রয়োজন।

file1আপনি যে প্যাটার্নটি সন্ধান করতে চান তা ধারণ করে ধরেই আপনার কমান্ডটি এখানে দেওয়া হয়েছে file2:

grep -aof <(tr '\n' '\0' < file1) <(tr '\n' '\0' < file2) | tr '\0' '\n'

আপনার প্রদত্ত ফাইলগুলির উদাহরণ আউটপুট:

A B
C D
E F
G H

ব্যাখ্যা:

  • <(tr '\n' '\0' < file1)সমান একটি ফিফো / নামক পাইপ / অস্থায়ী ফাইল-জাতীয় অবজেক্ট তৈরি করে যা file1সমস্ত নতুন লাইনের অক্ষরগুলির সাথে NUL টি অক্ষরে অনুবাদ হয়।
  • <(tr '\n' '\0' < file2)একই কাজ, কিন্তু জন্য file2
  • grep -f PATTERN_FILE INPUT_FILEভিতরে থেকে প্যাটার্নগুলির জন্য অনুসন্ধান PATTERN_FILEকরে INPUT_FILE
  • -aপতাকা grepবাইনারি ফাইল ম্যাচিং দেয়। এটি প্রয়োজনীয় কারণ অন্যথায় এটি এমন ফাইলগুলিকে এড়িয়ে যেতে পারে যাতে প্রিন্টযোগ্য অক্ষরগুলির মতো থাকে \0
  • এর -oপতাকা grepএটি কেবল মিলে যাওয়া ক্রমটি মুদ্রণ করে, যেখানে এটি পাওয়া গেছে সেখানে পুরো রেখাটি নয়।
  • | tr '\0' '\n' বাম পাশের কমান্ডের আউটপুট থেকে সমস্ত এনএলএইচ অক্ষরকে নতুন লাইন অক্ষরে অনুবাদ করে।


3

খাঁটি বাশে মজা করার জন্য

mapfile -t <file1
while read line ; do
    [ "$line" = "${MAPFILE[i++]}" ] || { ["$line" = "$MAPFILE" ] && i=1 || i=0; }
    [ $i -eq ${#MAPFILE[*]} ] && { printf "%s\n" "${MAPFILE[@]}"; i=0; }
done <file2

3

এখানে কিছুটা মার্জিত grep+ perl:

$ grep -Pzo "$(perl -pe 's/\n/\\n/g' file1.txt )"  file2.txt                    
A B
C D
E F
G H

তবে, একটি বড় ক্যাচ আছে। তাহলে সেখানে একটি trailing হয় সম্পর্কে newline file1, প্যাটার্ন সঠিক হবে না, অন্য কথায়: A B\nC D\nE F\nG H\n\n

(পার্ল অংশ সরবরাহের জন্য বিশেষ ধন্যবাদ @ ইটারডন)

কোস্টা হিসাবে উল্লেখ করা হয়েছে যে, perl -0pe 's/\n(\n+$)?/\\n/g' নতুন perlকমান্ডের জায়গায় অন্যটি নতুন লাইনে এড়াতে ব্যবহার করতে পারেfile1.txt


1
যদি সেখানে একটি পিছনে নতুনলাইন থাকে এবং এটি ওপি না থেকে সন্ধান করতে চায় perl -0pe 's/\n(\n+$)?/\\n/g'। ছাড়া Regex modificator তারও চেয়ে বেশী। -0g
কস্টাস

1

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

import sys
find = open(sys.argv[1]).read()
hay = open(sys.argv[2]).read()
print("The text occurs", hay.count(find), "times")

আপনি file1যতবার মেলে ততবার মুদ্রণ করতে চান ? এটির সাথে শেষ লাইনটি প্রতিস্থাপন করুন:

print(find * hay.count(find))

আপনি যদি সত্যিই এটি করতে চান তবে আপনি কমান্ডলাইন কল বা ওরফে সমস্ত কিছু প্যাক করতে পারেন:

python -c 'import sys; print("The text occurs", open(sys.argv[2]).read().count(open(sys.argv[1]).read()), "times")' file1 file2

1
grep -lir 'A B \n D C \n whatever' ./folder_to_search

ফলাফলটি হুবহু পাঠ্য মিলের সাথে সমস্ত ফাইল হবে


0

পাইথন ব্যবহারের জন্য এখানে আরও একটি পদ্ধতি রয়েছে (যার python3 3.5.2সাথে কোনও অভিযোগ ছাড়াই পরীক্ষিত pylint3 1.5.6):

""" Locate entire file contents contiguous in other file """

import sys
import re
from mmap import mmap, PROT_READ

def memmap(name):
    """ Return memoryview of readonly mmap """
    with open(name, 'rb') as file:
        return memoryview(mmap(file.fileno(), 0, access=PROT_READ))

def finder(needle, haystack):
    """ Return iterator """
    return re.compile(re.escape(needle)).finditer(haystack)

print(tuple(finder(*(memmap(name) for name in sys.argv[1:3]))))

কমান্ড লাইন আর্গুমেন্টের মাধ্যমে পরিচালনার sys.argvবিষয়টি স্বীকারযোগ্যভাবে সরল। আপনি finderযে দুটি memoryviewবস্তুটিতে প্রবেশ করেন তার ফেরত মূল্য সহ আপনি আরও অনেকগুলি কাজ করতে পারেন , এটি পাস করার পাশাপাশি tupleSRE_Matchপুনরাবৃত্তি দ্বারা ফিরে আসা প্রতিটি আইটেমের finderবিভিন্ন পদ্ধতি রয়েছে, একটি নমুনা যার printআউটপুট সংক্ষিপ্ত করা হয় ( spanউদাহরণস্বরূপ, প্রতিটি ম্যাচের বাইট পরিসরটি বলে)।

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