मेरे पास एक 8 जीबी लॉग फ़ाइल (रेल उत्पादन लॉग) है। मुझे कुछ तिथियों (लाइनों) के बीच इसे काटने की आवश्यकता है। ऐसा करने के लिए मैं किस कमांड का उपयोग कर सकता हूं?
sed
आसानी से कर लेंगे।
मेरे पास एक 8 जीबी लॉग फ़ाइल (रेल उत्पादन लॉग) है। मुझे कुछ तिथियों (लाइनों) के बीच इसे काटने की आवश्यकता है। ऐसा करने के लिए मैं किस कमांड का उपयोग कर सकता हूं?
sed
आसानी से कर लेंगे।
जवाबों:
कुछ इस तरह
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"
sed
मिलान awk
किया जा सकता है , और यह वास्तव में थोड़ा तेज था।
FOO और BAR समावेशी के बीच सब कुछ प्रिंट करने के लिए, प्रयास करें:
$ sed -n '/FOO/,/BAR/p' file.txt
यह वही करेगा जो आप चाहते हैं ...
पैरामीटर दिनांक को छोड़कर और शामिल दोनों को दिखाया गया है।
# 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"
if
विवरण की अवधि है (प्रति पंक्ति 1 भी नहीं) यानी। तर्क प्रवाह प्रभावी रूप से समान है, और रन टाइम में अंतर को नैनोसेकंड में गिना जाएगा .... एकमात्र कारण जो मैंने "और" का उपयोग नहीं किया, वह यह है कि यह प्रभावी रूप से मेरी पहली स्क्रिप्ट है (एक दिन से अलग 4 साल पहले जब मैंने कुछ उदाहरणों के साथ खेला था) ... और यह पहली व्यावहारिक शाखा तंत्र है जो मैंने पाया ... (और जैसा कि उल्लेख किया गया है। यह उतना ही तेज है) .. मैं उदारतापूर्वक कोशिश का उपयोग करता हूंawk
sed
q
यदि आपकी लॉग फ़ाइल में आपके पास इस प्रारूप में दिनांक हैं 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
फ़ाइलों के इस आकार के साथ काम करना हमेशा कठिन होता है।
आगे का एक तरीका इस फ़ाइल को एक छोटे से जोड़े में विभाजित करने के लिए हो सकता है, ऐसा करने के लिए आप विभाजन आदेश का उपयोग कर सकते हैं।
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 ऑपरेशन के लिए व्यर्थ है, लेकिन यदि खोज पैटर्न अधिक जटिल हो जाता है तो यह तेज हो सकता है।
perl -wlne '/^2011-02-24/ .. /^2011-02-25/ and print' log_file