लॉग फ़ाइल से भाग कैसे काटें?


18

मेरे पास एक 8 जीबी लॉग फ़ाइल (रेल उत्पादन लॉग) है। मुझे कुछ तिथियों (लाइनों) के बीच इसे काटने की आवश्यकता है। ऐसा करने के लिए मैं किस कमांड का उपयोग कर सकता हूं?


1
हे दोस्तों, यह सवाल एक बड़ी फ़ाइल के बारे में है , इसलिए यह "एंट अप!" .. समय मायने रखता है ... मैंने एक वास्तविक 8 जीबी फ़ाइल पर 85904064 लाइनों (प्रति पंक्ति 100 वर्ण) के साथ पसंदीदा सिड स्क्रिप्ट का परीक्षण किया है। मुझे sed पसंद है, लेकिन जैसा कि यह खड़ा है, sed स्क्रिप्ट पूरी फ़ाइल को हर बार स्कैन करती है । यह औसत स्क्रिप्ट से दो बार धीमी गति से बनाता है जैसे कि एक्टिंग स्क्रिप्ट जो बाहर निकलती है, जब-जब-जो पाया जाता है ... मुझे लगता है कि (?) सेड स्क्रिप्ट को दूसरी अभिव्यक्ति के लिए d के बजाय aq की आवश्यकता हो सकती है ... परीक्षा परिणाम यहां हैं: पेस्ट .ubuntu.com / 573,477 .. इसके अलावा, यह उचित उत्पादन का उत्पादन नहीं करता .. अंत asoundmove के जवाब में मेरी टिप्पणी देखें।
पीटर

asoundmove के नए सेड संस्करण ने गति के मुद्दे को संबोधित किया था, और यह अब awks की गति से मेल खाता है। और नया वर्जन अब डेटा को सही ढंग से आउटपुट करता है ... अधिक विस्तार के लिए उसकी टिप्पणी देखें।
पीटर

मैंने अभी देखा कि आपने "कट" (जिसका आमतौर पर अर्थ हटा दिया जाता है) कहा है ... क्या आप वास्तव में "कट" का अर्थ रखते हैं, या क्या आपका मतलब "कॉपी" है? .... यदि आपने "कट" का अर्थ किया, तो sedआसानी से कर लेंगे।
पीटर

जवाबों:


12

कुछ इस तरह

sed '1,/last date prior to chunk/d;/first date after chunk/,$d' logfile | tee cut-log | less

tee cut-logआपको स्क्रीन पर देखने की अनुमति देता है कि फ़ाइल में क्या रखा जा रहा है cut-log

संपादित करें:

Fred.bear के सटीक मानकों को पूरा करने के लिए, यहाँ एक सॉल्यूशन सॉल्यूशन है (हालाँकि यकीनन ऑक सॉल्यूशन एक बहुत पहले की बात है:

b=BB; e=EE ;echo -e "AA\nAA\nBB\nBB\nCC\nCC\nDD\nDD\nEE\nEE\nFF\nFF" | sed -n ":b;/$b/b p;n;b b;:p;p;n;/$e/b e;b p;:e;p;n;/$e/b e;q"


3
@ डोगबेन: हाँ, हाँ। संपादित। मुझे यकीन है कि आप कभी-कभी इष्टतम कोड से कम लिखते हैं, क्या यह इस तरह की कठोर टिप्पणी के लायक है?
asoundmove

1
नोट: यदि एक ही तिथि के साथ लगातार कई 'प्रथम-तिथि' लाइनें हैं, लेकिन सभी पहले नहीं हटाई जाएंगी, और उन्हें आउटपुट पर पेश किया जाएगा ... बस कुछ जागरूक होने के लिए ... (यह इस पर निर्भर करता है) स्थिति)
पीटर

1
... लेकिन, भले ही मैं एक प्रो-सेड ++, मुझे लगता है कि यह विशेष कार्य अपनी सीमा से परे है, एक 'स्वयं के व्यक्तिगत उपकरण के अलावा अन्य किसी भी चीज के लिए .. यहाँ मुख्य मुद्दा है इस मामले में sed (आपका, और मेरा .. मैं आपके जैसे ही करने के लिए sed पाने में कामयाब रहा .. यह भी 1% के भीतर चला गया) .. वापस मुख्य मुद्दे पर .. (जो कि awk पर लागू नहीं होता है) .... बग (फिक्स नहीं): उस तिथि के बारे में, जो लॉग के दायरे में मान्य है, लेकिन वास्तव में 1 arg के मामले में लॉग वसीयत में मौजूद नहीं है, क्योंकि sed कुछ भी नहीं छापने के लिए, और 2nd arg के मामले में, sed wil प्रिंट सब कुछ पहली तारीख के बाद! ... और ...
पीटर

1
एक और, फिक्सेबल बग: क्या यह वर्तमान में डेटा प्रोटेक्शन सहित किसी भी पंक्ति में किसी भी पंक्ति में मेल खाता है, लेकिन यह सिर्फ एक रेगीक्स ट्विक है .. और किसी को भी इसका उपयोग करने की इच्छा के लिए, शायद आप टिप्पणी कर सकते हैं कि आर्ग्स अब पहले का उल्लेख करते हैं। अंतिम तिथि सीमा में (-1 और +1 नहीं) .. और अंत में .. मेरे "सटीक मानक" मेरे नहीं हैं। मैं केवल प्रश्नकर्ताओं के अनुरोध का संदेशवाहक हूं ... उपयोगकर्ता यह नोटिस करेगा कि क्या वह अनुरोध के अनुसार काम करता है, या नहीं .. यह मेरे लिए बहुत अच्छा सवाल है .. मैंने बहुत कुछ सीखा है :) और मुझे खुशी है यह जानने के लिए कि गति के लिए sedमिलान awkकिया जा सकता है , और यह वास्तव में थोड़ा तेज था।
पीटर

6

FOO और BAR समावेशी के बीच सब कुछ प्रिंट करने के लिए, प्रयास करें:

$ sed -n '/FOO/,/BAR/p' file.txt

1
नोट: यह केवल लगातार BARS की एक श्रृंखला का पहला BAR प्रिंट करेगा ...
पीटर

एक और ध्यान दें ... बड़ी समस्या है कि या तो तारीखें डेटा में मौजूद नहीं हैं .. यदि अंतिम तिथि मौजूद नहीं है, तो ईओडी तक पहुंचने तक सीड आउटपुट लाइनें बनाए रखेगा।
पीटर।

5

यह वही करेगा जो आप चाहते हैं ...
पैरामीटर दिनांक को छोड़कर और शामिल दोनों को दिखाया गया है।

# set Test args
set  2011-02-24  2011-02-26  "junk"

from="$1"
till="$2"
file="$3"

# EITHER ====                              +++++++++  
# Ouptut lines between two parameter dates INCLUDING the parameter dates
  awk -v from=$from -v till=$till '
    ($2 >= from) && ($2 <= till) { print $0 ; next }
    ($2 > till) { exit }' "$file"

# OR ========                              ---------
# Ouptut lines between two parameter dates EXCLUDING the parameter dates
  awk -v from=$from -v till=$till '
    ($2 > from) && ($2 < till) { print $0 ; next }
    ($2 >= till) { exit }' "$file"

यह क्षेत्र 2 में एक (सॉर्ट की गई) तारीख के लिए परीक्षण करता है ... यहां परीक्षण डेटा के लिए एक उदाहरण है

    98  2011-02-05 xxxx
    99  2011-02-05 xxxx
   100  2011-02-06 xxxx
   101  2011-02-06 xxxx

और यहाँ परीक्षण-डेटा जनरेटर है


मैं इसे लिखूँगा (उदाहरण के लिए पहले वाला) थोड़ा और अधिक इस प्रकार: awk -v from="$from" -v till="$till" '($2 >= from) { if ($2 <= till) { print } else { exit }' "$file"
asoundmove

@asoundmove: हाँ, यह बेहतर लग सकता है, और यह निश्चित रूप से अधिक पारंपरिक है , लेकिन वास्तव में, इसका निष्पादन समय कुल 1 अतिरिक्त ifविवरण की अवधि है (प्रति पंक्ति 1 भी नहीं) यानी। तर्क प्रवाह प्रभावी रूप से समान है, और रन टाइम में अंतर को नैनोसेकंड में गिना जाएगा .... एकमात्र कारण जो मैंने "और" का उपयोग नहीं किया, वह यह है कि यह प्रभावी रूप से मेरी पहली स्क्रिप्ट है (एक दिन से अलग 4 साल पहले जब मैंने कुछ उदाहरणों के साथ खेला था) ... और यह पहली व्यावहारिक शाखा तंत्र है जो मैंने पाया ... (और जैसा कि उल्लेख किया गया है। यह उतना ही तेज है) .. मैं उदारतापूर्वक कोशिश का उपयोग करता हूंawksedq
पीटर

मुझे समझ नहीं आ रहा है कि आप इस विधि में टेक्स्ट फ़ाइल का नाम और स्थान कहाँ दें? क्या कोई मुझे मेरी मूर्खता के माध्यम से देखने में मदद कर सकता है
जाइल्स

4

यदि आपकी लॉग फ़ाइल में आपके पास इस प्रारूप में दिनांक हैं YYYY-MM-DD, तो, कहने के लिए सभी प्रविष्टियों को खोजने के लिए, 2011-02-10, आप कर सकते हैं:

grep 2011-02-10 log_file

अब, कहते हैं, यदि आप 2011-02-10 और 2011-02-11 के लिए प्रविष्टियों को खोजना चाहते हैं, तो, फिर से उपयोग करें grepलेकिन कई पैटर्न के साथ:

grep -E '2011-02-10|2011-02-11' log_file

अच्छा। यह "के रूप में विज्ञापित" काम करता है :) ... हालांकि, grepपूरी फ़ाइल को खोजेगा, भले ही फ़ाइल की शुरुआत में तिथि सीमा हो । औसतन यह एक खोज के समय को दोगुना कर देता है, जब "एक्जिट-आफ्टर-अंतिम-आइटम-इन-रेंज" की तुलना में ... मैं केवल प्रश्न में उल्लिखित 8 जीबी फ़ाइल आकार के कारण इसका उल्लेख करने के लिए परेशान कर रहा हूं, आपका grep समय परिणाम यहां के sed उदाहरण के समान हैं (1min 58sec)। यहाँ मेरे समय परीक्षणों के परिणामों की लिंक दी गई है: paste.ubuntu.com/573477
Peter.O

1

फ़ाइलों के इस आकार के साथ काम करना हमेशा कठिन होता है।

आगे का एक तरीका इस फ़ाइल को एक छोटे से जोड़े में विभाजित करने के लिए हो सकता है, ऐसा करने के लिए आप विभाजन आदेश का उपयोग कर सकते हैं।

split -d -l 50000 ToBigFile.data file_

यहां तक ​​कि यह विभाजित है आप अभी भी फ़ाइल के साथ काम कर सकते हैं जैसे कि लूप के लिए बैश का उपयोग करने वाला एक होगा

for f in `ls file_*`; do cat $f; done;

लेकिन बिल्ली के बजाय आप अवांछित डेटा से छुटकारा पाने के लिए उल्टे ग्रेप का उपयोग कर सकते हैं, जो इसके लिए अप्रासंगिक है। (या आप की जरूरत है कि शोधन के प्रकार)।

इस बिंदु पर आप बहुत सारी छोटी फ़ाइलों के साथ काम करेंगे, और ऊपर बताई गई अन्य कमांड बहुत सारी छोटी फाइलों पर स्मूथ काम करेगी।

और जब आप कर रहे हैं, तो आप नई छोटी फ़ाइल को फिर से बनाने के लिए लूप के लिए एक दूसरे का उपयोग कर सकते हैं।

for f in `ls file_*`; do cat $f >> NewFile.data ; done;

अपडेट चूंकि हम डेटा को कई फ़ाइलों में विभाजित करना शुरू करते हैं, इसलिए हार्डड्राइव के साथ बहुत काम होने वाला है और इसमें समय लगता है। (इस प्रश्न में स्पष्ट रूप से 5 मिनट)।

दूसरी ओर अगले कदम शायद तेज होंगे।

तो यह विधि शायद सरल grep, awk, sed ऑपरेशन के लिए व्यर्थ है, लेकिन यदि खोज पैटर्न अधिक जटिल हो जाता है तो यह तेज हो सकता है।


3
जोहान्म, यह औसतन केवल 1 मिनट का समय लेता है, औसतन, मेरे कंप्यूटर पर 8 जीबी लॉग फ़ाइल खोजने के लिए, और एक ही कंप्युटर पर, सिर्फ इनिटल फ़ाइल विभाजन, 4min 43sec लेता है ... :)
पीटर.ओ।

मान लीजिए कि आप छोटी फ़ाइलों पर उन awk और sed समय को 50% तक काट सकते हैं। तब हमें अभी भी उन ऑपरेशनों में से 10 से अधिक करने की आवश्यकता है इससे पहले कि हम कुल समय पर हासिल करें ... इसलिए शायद कुछ विभाजन के लिए फ़ाइल विभाजन सबसे अच्छा विचार नहीं है ...
जोहान

Awk script (10) अलग-अलग खोज परिणामों को 10 फ़ाइलों में बदलने के लिए (आसानी से) संशोधित की जा सकती है। एक एकल पास, लेकिन यह वास्तव में रिपोर्ट का उत्पादन करते समय रीड को धीमा कर देगा ... एसडीडी भी ऐसा ही कर सकता है, लेकिन जैसा कि मैंने किया asoundmove की टिप्पणियों में उल्लिखित है, अगर कोई विशेष तिथि / समय लॉग में कोई प्रविष्टि नहीं है (जैसे, आप घंटे से खोज रहे हैं) तो sed विफल हो जाएगा .. मैं sed का उपयोग बहुत करता हूं और यह अत्यंत उपयोगी है, लेकिन इसकी सीमाएं हैं ... यहाँ sed बनाम awk का उपयोग करने के बारे में एक सामान्य प्रश्न है। मैं जरूरी नहीं कि सभी इससे सहमत हों, लेकिन मैं देख सकता हूँ कि उनका क्या मतलब है ... sed.sourceforge.net/sedfaq6.html
पीटर। ओ

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.