उलटा कर देना


44

मान लीजिए, मेरे पास एक बहुत बड़ी पाठ फ़ाइल है (लगभग 10.000.000 पंक्तियाँ)। मुझे grepअंत से इसकी आवश्यकता है और परिणाम को फ़ाइल में सहेजें। कार्य को पूरा करने का सबसे कुशल तरीका क्या है?


10
उपयोग tacऔर grepप्राप्त करने के लिए आप क्या चाहते हैं।
वैलेंटाइन बजरमी

1
पोस्ट किए गए उत्कृष्ट समाधानों के अलावा, जीएनयू grepमें एक --max-count (number)स्विच होता है जो एक निश्चित संख्या में मैचों के बाद गर्भपात करता है, जो आपके लिए दिलचस्प हो सकता है।
उलरिच श्वार्ज़

@ val0x00ff क्या आप इस प्रश्न पर एक नज़र डाल सकते हैं
c0rp

क्या आप जानते हैं कि आपके पास कितनी हिट होंगी? जब आपको लगता है कि आपके grep को 3 लाइनें मिलेंगी, तो grepping शुरू करें और बाद में उल्टा करें।
वाल्टर ए

जवाबों:


46

tac / grep समाधान

tac file | grep whatever

या थोड़ा और अधिक प्रभावी:

grep whatever < <(tac file)

500MB फ़ाइल के साथ समय:

real    0m1.225s
user    0m1.164s
sys     0m0.516s

sed / grep समाधान:

sed '1!G;h;$!d' | grep whatever

500MB फ़ाइल के साथ समय: 10+ मिनट के बाद निरस्त कर दिया गया।

awk / grep समाधान:

awk '{x[NR]=$0}END{while (NR) print x[NR--]}' file | grep whatever

500MB फ़ाइल के साथ समय:

real    0m5.626s
user    0m4.964s
sys     0m1.420s

पर्ल / grep समाधान:

perl -e 'print reverse <>' file | grep whatever

500MB फ़ाइल के साथ समय:

real    0m3.551s
user    0m3.104s
sys     0m1.036s

2
sed, awkऔर perl(इस विधि के साथ) ठीक नहीं हैं क्योंकि उन्होंने शुरुआत से ही फ़ाइल पढ़ी है, जो बहुत ही अक्षम है। मुझे लगता है कि tacसही काम करता है।
vinc17

1
@ vinc17 हाँ, समय आँकड़े आपके द्वारा कही गई बातों को इंगित करते हैं।
अराजकता

2
@ val0x00ff < <(tac filename)एक पाइप की तरह तेज होना चाहिए: दोनों मामलों में, कमांड समानांतर में चलते हैं।
vinc17

7
यदि आप दक्षता के लिए जा रहे हैं, तो बेहतर होगा tacकि जीआरईपी के बाद रखा जाए । यदि आपको १०,०००,००० लाइन फाइल मिली है, तो केवल २ मैचों के साथ, tacकेवल २ लाइनों को उल्टा करना होगा, १० मी नहीं। grepअभी भी पूरी तरह से किसी भी तरह से गुजरना है।
पैट्रिक

3
आप डाल दिया tacके बाद grep, यह एक पाइप से पढ़ने हो जाएगा और इसलिए मांग नहीं कर सकते। अगर यह पाया लाइनों की संख्या बड़ी है, तो यह कम कुशल (या पूरी तरह से विफल) कर देगा।
जेजेन्स

17

यह समाधान मदद कर सकता है:

tac file_name | grep -e expression

3
tacGNU कमांड है। अधिकांश अन्य प्रणालियों पर, समकक्ष है tail -r
स्टीफन चेज़लस

@ स्टीफन: कम से कम कुछ यूनिक्स सिस्टम पर, tail -rछोटी संख्या में लाइनों तक सीमित है, यह एक मुद्दा हो सकता है।
RedGrittyBrick

1
@RedGrittyBrick, क्या आपके पास इसके लिए कोई संदर्भ है, या आप कृपया बता सकते हैं कि किन प्रणालियों में वह सीमा है?
स्टीफन चेज़लस

@ स्टीफनचेज़लस, के tail -r /etc/passwdसाथ विफल tail: invalid option -- 'r'। मैं Coreutils-8.21-21.fc20.x86_64 का उपयोग कर रहा हूं।
क्रिस्टियन सियुपिटु

@CristianCiupitu, जैसा कि मैंने कहा, GNU के पास tac(और केवल GNU tac है) कई अन्य यूनियनों के पास है tail -r। GNU tailसमर्थन नहीं करता-r
स्टीफन चेज़ेलस

10

यह पहला मैच ढूंढते ही बाहर निकल जाता है:

 tac hugeproduction.log | grep -m1 WhatImLookingFor

पहले दो मैचों से पहले और बाद में 5 लाइनें दी गई हैं:

 tac hugeproduction.log | grep -m2 -A 5 -B 5 WhatImLookingFor

याद रखें -iकि तब तक उपयोग न करें (जब तक आप असंवेदनशील न हों) आपको जीआरई धीमा करना पड़ेगा।

यदि आप उस सटीक स्ट्रिंग को जानते हैं जिसे आप खोज रहे हैं तो विचार करें fgrep(फिक्स्ड स्ट्रिंग)

 tac hugeproduction.log | grep -F -m2 -A 5 -B 5 'ABC1234XYZ'

9

यदि फ़ाइल वास्तव में बड़ी है, तो मेमोरी में फिट नहीं हो सकती है, मैं फ़ाइल केPerl साथ उपयोग करूंगा :: ReadBackwards मॉड्यूल से CPAN:

$ cat reverse-grep.pl
#!/usr/bin/perl

use strict;
use warnings;

use File::ReadBackwards;

my $pattern = shift;
my $rev = File::ReadBackwards->new(shift)
    or die "$!";

while (defined($_ = $rev->readline)) {
    print if /$pattern/;
}

$rev->close;

फिर:

$ ./reverse-grep.pl pattern file

इस दृष्टिकोण का लाभ यह है कि आप पर्ल को कुछ भी करने के लिए ट्विक कर सकते हैं।
zzapper

1
@zzapper: यह स्मृति कुशल भी है, क्योंकि जब यह मेमोरी में स्लरप फाइल की बजाय लाइन द्वारा फाइल लाइन पढ़ता है tac
15ong

किसी को भी इस के लिए एम समर्थन जोड़ सकते हैं? मैं असली फाइलों पर परीक्षण करना चाहता हूं। देखें: gist.githubusercontent.com/ychaouche/…
ychaouche
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.