awk 'FNR == 1 { f1=f2=f3=0; };
/one/ { f1++ };
/two/ { f2++ };
/three/ { f3++ };
f1 && f2 && f3 {
print FILENAME;
nextfile;
}' *
আপনি যদি জিজেপ করা ফাইলগুলি স্বয়ংক্রিয়ভাবে পরিচালনা করতে চান তবে হয় এটির সাহায্যে একটি লুপটিতে চালান zcat
(ধীর এবং অদক্ষ কারণ আপনি awk
প্রতিটি ফাইলের জন্য একবার লুপে অনেকবার ঝাঁকিয়ে পড়বেন ) অথবা একই অ্যালগরিদমটিতে আবার লিখতে perl
পারেন এবং IO::Uncompress::AnyUncompress
লাইব্রেরি মডিউলটি ব্যবহার করতে পারেন যা বিভিন্ন ধরণের সংকুচিত ফাইলগুলি (gzip, zip, bzip2, lzop) ডিকম্প্রেস করুন। বা পাইথনে, এতে সংক্রামিত ফাইলগুলি পরিচালনা করার জন্য মডিউলও রয়েছে।
এখানে এমন একটি perl
সংস্করণ যা IO::Uncompress::AnyUncompress
কোনও সংখ্যক নিদর্শন এবং যে কোনও ফাইলের নাম (যে কোনও সরল পাঠ্য বা সংকীর্ণ পাঠ্য ধারণ করে) এর জন্য অনুমতি দেয়।
আগের সমস্ত আরোগুলি --
অনুসন্ধানের নিদর্শন হিসাবে বিবেচিত হয়। পরে সমস্ত আরগগুলি --
ফাইলের নাম হিসাবে বিবেচনা করা হয়। এই কাজের জন্য আদিম কিন্তু কার্যকর বিকল্প হ্যান্ডলিং। উন্নত বিকল্প হ্যান্ডলিং (উদাহরণস্বরূপ -i
কেস-সংবেদনশীল অনুসন্ধানের জন্য কোনও বিকল্পকে সমর্থন করা ) Getopt::Std
বা Getopt::Long
মডিউলগুলির সাহায্যে অর্জন করা যেতে পারে ।
এটি এর মতো চালান:
$ ./arekolek.pl one two three -- *.gz *.txt
1.txt.gz
4.txt.gz
5.txt.gz
1.txt
4.txt
5.txt
(আমি ফাইলগুলি এখানে তালিকাবদ্ধ করব না {1..6}.txt.gz
এবং {1..6}.txt
এখানে ... সেগুলিতে পরীক্ষার জন্য "এক" "দুটি" "তিন" "চার" "পাঁচ" এবং "ছয়" শব্দগুলির কিছু বা সমস্ত কিছু রয়েছে contain উপরের আউটপুটে তালিকাভুক্ত ফাইলগুলি তিনটি অনুসন্ধান নিদর্শন রয়েছে DO এটি নিজের নিজের ডেটা দিয়ে নিজেই পরীক্ষা করুন)
#! /usr/bin/perl
use strict;
use warnings;
use IO::Uncompress::AnyUncompress qw(anyuncompress $AnyUncompressError) ;
my %patterns=();
my @filenames=();
my $fileargs=0;
# all args before '--' are search patterns, all args after '--' are
# filenames
foreach (@ARGV) {
if ($_ eq '--') { $fileargs++ ; next };
if ($fileargs) {
push @filenames, $_;
} else {
$patterns{$_}=1;
};
};
my $pattern=join('|',keys %patterns);
$pattern=qr($pattern);
my $p_string=join('',sort keys %patterns);
foreach my $f (@filenames) {
#my $lc=0;
my %s = ();
my $z = new IO::Uncompress::AnyUncompress($f)
or die "IO::Uncompress::AnyUncompress failed: $AnyUncompressError\n";
while ($_ = $z->getline) {
#last if ($lc++ > 100);
my @matches=( m/($pattern)/og);
next unless (@matches);
map { $s{$_}=1 } @matches;
my $m_string=join('',sort keys %s);
if ($m_string eq $p_string) {
print "$f\n" ;
last;
}
}
}
একটি হ্যাশটিতে %patterns
নিদর্শনগুলির সম্পূর্ণ সেট থাকে যা ফাইলগুলিতে প্রতিটি সদস্যের কমপক্ষে একটিতে থাকা
$_pstring
স্ট্রিংটি সেই হ্যাশটির সাজানো কীগুলি ধারণ করে। স্ট্রিংটিতে হ্যাশ $pattern
থেকে তৈরি একটি প্রাক-সংকলিত নিয়মিত প্রকাশ রয়েছে %patterns
।
$pattern
প্রতিটি ইনপুট ফাইলের প্রতিটি লাইনটির সাথে তুলনা করা হয় ( কেবল একবারে /o
সংকলন করতে পরিবর্তক ব্যবহার করে $pattern
আমরা জানি যে এটি রান চলাকালীন কখনই পরিবর্তন হবে না) এবং map()
প্রতিটি ফাইলের জন্য ম্যাচগুলি সমন্বিত একটি হ্যাশ (% s) তৈরি করতে ব্যবহৃত হয়।
বর্তমান ফাইলে যখনই সমস্ত নিদর্শন দেখা গেছে (তুলনায় $m_string
(সাজানো কীগুলি %s
সমান হলে $p_string
)), ফাইলের নামটি মুদ্রণ করুন এবং পরবর্তী ফাইলটিতে যান ip
এটি বিশেষত দ্রুত সমাধান নয়, তবে অযৌক্তিকভাবে ধীর নয়। প্রথম সংস্করণটি 4 এম 58 সেকেন্ডে 74 এমবি মূল্যের সংকুচিত লগ ফাইলগুলিতে তিনটি শব্দ অনুসন্ধান করতে (মোট 937 এমবি সঙ্কুচিত) search এই বর্তমান সংস্করণটি 1m13s সময় নেয়। সম্ভবত আরও আশাবাদীগুলি তৈরি করা যেতে পারে।
একটি সুস্পষ্ট অপ্টিমাইজেশন হ'ল এটি সমান্তরালভাবে ফাইলের সাবসেটে একাধিক অনুসন্ধান চালানোর জন্য xargs
এর -P
ওরফে সাথে ব্যবহার করে --max-procs
। এটি করার জন্য, আপনাকে ফাইলের সংখ্যা গণনা করতে হবে এবং আপনার সিস্টেমের কর / সিপাস / থ্রেডের সংখ্যা দ্বারা বিভক্ত করতে হবে (এবং 1 যোগ করে গোল করবে)। যেমন আমার নমুনা সেটে 269 টি ফাইল অনুসন্ধান করা হয়েছিল এবং আমার সিস্টেমে 6 টি কর (একটি এএমডি 1090T) রয়েছে, তাই:
patterns=(one two three)
searchpath='/var/log/apache2/'
cores=6
filecount=$(find "$searchpath" -type f -name 'access.*' | wc -l)
filespercore=$((filecount / cores + 1))
find "$searchpath" -type f -print0 |
xargs -0r -n "$filespercore" -P "$cores" ./arekolek.pl "${patterns[@]}" --
এই অপ্টিমাইজেশনের সাথে, সমস্ত 18 টি মিলছে ফাইলগুলি সন্ধান করতে কেবল 23 সেকেন্ড সময় নিয়েছে অবশ্যই, অন্য যে কোনও সমাধানের সাথে এটি করা যেতে পারে। দ্রষ্টব্য: আউটপুটে তালিকাভুক্ত ফাইল নামগুলির ক্রম পৃথক হবে, তাই পরে যদি তা গুরুত্বপূর্ণ হয় তবে তা বাছাই করা দরকার।
@Arekolek দ্বারা উল্লিখিত হিসাবে, একাধিক zgrep
গুলি এর সাথে এটি উল্লেখযোগ্যভাবে দ্রুত করতে পারে find -exec
বা xargs
করতে পারে তবে এই স্ক্রিপ্টটিতে অনুসন্ধানের জন্য অনেকগুলি নিদর্শনকে সমর্থন করার সুবিধা রয়েছে এবং এটি বিভিন্ন ধরণের সংক্ষেপণের সাথে কাজ করতে সক্ষম।
যদি স্ক্রিপ্টটি প্রতিটি ফাইলের প্রথম প্রথম 100 টি লাইন পরীক্ষা করার মধ্যে সীমাবদ্ধ থাকে তবে এটি 0.6 সেকেন্ডের মধ্যে তাদের সমস্ত (269 ফাইলের 74MB নমুনায়) মাধ্যমে চলে। এটি যদি কিছু ক্ষেত্রে কার্যকর হয় -l 100
তবে এটি একটি কমান্ড লাইন বিকল্প হিসাবে তৈরি করা যেতে পারে (উদাঃ ) তবে এর সাথে সমস্ত মিলে যাওয়া ফাইলগুলি খুঁজে না পাওয়ার ঝুঁকি রয়েছে ।
বিটিডব্লিউ, এর জন্য ম্যান পেজ অনুসারে, সংক্ষিপ্ত রূপগুলি IO::Uncompress::AnyUncompress
সমর্থিত:
একটি শেষ (আমি আশা করি) অপ্টিমাইজেশন। ব্যবহারের PerlIO::gzip
মডিউল (যেমন ডেবিয়ান প্যাকেজ libperlio-gzip-perl
) পরিবর্তে IO::Uncompress::AnyUncompress
আমি সম্পর্কে নিচে সময় পেয়েছিলাম 3.1 সেকেন্ড লগ ফাইল আমার 74MB প্রক্রিয়াকরণের জন্য। পরিবর্তে একটি সাধারণ হ্যাশ ব্যবহার করে কিছু ছোট উন্নতি হয়েছে Set::Scalar
(যা IO::Uncompress::AnyUncompress
সংস্করণটির সাথে কয়েক সেকেন্ডও সাশ্রয় করেছে)।
PerlIO::gzip
/programming//a/1539271/137158 (যার জন্য গুগল অনুসন্ধানের সাথে পাওয়া গেছে perl fast gzip decompress
) দ্রুততম পার্ল বন্দুক হিসাবে সুপারিশ করা হয়েছিল
এটি ব্যবহার করে xargs -P
এটি একেবারেই উন্নত হয়নি। এমনকি এটি 0.1 থেকে 0.7 সেকেন্ড পর্যন্ত যে কোনও জায়গায় এটিকে ধীর করে ফেলবে বলে মনে হয়েছিল। (আমি চারটি রান চেষ্টা করেছিলাম এবং আমার সিস্টেম ব্যাকগ্রাউন্ডে অন্যান্য জিনিসগুলি করে যা সময়কে পরিবর্তন করবে)
দামটি হ'ল স্ক্রিপ্টটির এই সংস্করণটি কেবল জিজেপড এবং সঙ্কুচিত ফাইলগুলি পরিচালনা করতে পারে। গতি বনাম নমনীয়তা: এই সংস্করণটির জন্য 3.1 সেকেন্ডের IO::Uncompress::AnyUncompress
সাথে একটি xargs -P
মোড়কযুক্ত সংস্করণের জন্য 23 সেকেন্ডের (বা 1m13s ছাড়াই xargs -P
)।
#! /usr/bin/perl
use strict;
use warnings;
use PerlIO::gzip;
my %patterns=();
my @filenames=();
my $fileargs=0;
# all args before '--' are search patterns, all args after '--' are
# filenames
foreach (@ARGV) {
if ($_ eq '--') { $fileargs++ ; next };
if ($fileargs) {
push @filenames, $_;
} else {
$patterns{$_}=1;
};
};
my $pattern=join('|',keys %patterns);
$pattern=qr($pattern);
my $p_string=join('',sort keys %patterns);
foreach my $f (@filenames) {
open(F, "<:gzip(autopop)", $f) or die "couldn't open $f: $!\n";
#my $lc=0;
my %s = ();
while (<F>) {
#last if ($lc++ > 100);
my @matches=(m/($pattern)/ogi);
next unless (@matches);
map { $s{$_}=1 } @matches;
my $m_string=join('',sort keys %s);
if ($m_string eq $p_string) {
print "$f\n" ;
close(F);
last;
}
}
}
gzip
বন্ধুত্বপূর্ণ হওয়ার দরকার নেই , কেবলzcat
আগে ফাইলগুলি।