2012-08-29 13 views
9

मैंने PHP में एक टेक्स्ट फ़ाइल की अंतिम पंक्ति पॉपिंग के संबंध में question से पूछा, और अब, क्या शैल स्क्रिप्ट में तर्क को फिर से लिखना संभव है?खोल: एक बड़ी टेक्स्ट लॉग फ़ाइल की अंतिम पंक्ति को हटाएं

मैं इस कोशिश की अंतिम पंक्ति प्राप्त करने के लिए:

tail -n 1 my_log_file.log 

लेकिन मैं कैसे मैं अंतिम पंक्ति को हटाने और फाइल को सेव कर सकते हैं यकीन नहीं है।

पीएस दिया गया है कि मैं उबंटू सर्वर का उपयोग करता हूं।

उत्तर

9

(समाधान sch's answer पर आधारित है तो क्रेडिट उसे जाना चाहिए/उसकी)

यह दृष्टिकोण आप कुशलतापूर्वक फ़ाइल की अंतिम पंक्ति को पुनः प्राप्त करने और उस लाइन को हटाने के लिए फ़ाइल काट-छांट करने की अनुमति देगा। यह बड़े इनपुट के साथ बेहतर ढंग से सौदा कर सकता है क्योंकि फाइल अनुक्रमिक रूप से नहीं पढ़ी जाती है।

# retrieve last line from file 
LAST=$(tail -n 1 my_log_file.log) 

# truncate file 
let TRUNCATE_SIZE="${#LAST} + 1" 
truncate -s -"$TRUNCATE_SIZE" my_log_file.log 

# ... $LAST contains 'popped' last line 

ध्यान रहे कि यदि फ़ाइल tail और truncate के लिए कॉल के बीच संशोधित किया गया है अपेक्षा के अनुरूप काम नहीं होगा।

+1

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

+0

इसके अलावा, 'truncate' _bytes_ में आकार की अपेक्षा करता है, जबकि '$ {# LAST}' वर्णों की संख्या में' $ LAST' की लंबाई की गणना करता है। आप बराबर होने के लिए लोकेल को सी में सेट करना चाहते हैं। अन्यथा, अगर अंतिम पंक्ति में बहु-बाइट वर्ण होते हैं तो यह ठीक से काम नहीं करेगा। –

4

एक ही रास्ता है:

sed '$d' <f1> f2 ; mv f2 f1 
+0

मुझे यह समझ में नहीं आता है। 'f2' और' f1' क्या है? – Raptor

+0

मुझे देर हो चुकी है लेकिन यह मेरा पसंदीदा समाधान है। आप sed's "-i" ध्वज का उपयोग करके जगह बदल सकते हैं: "sed -i -e '$ d' my_log_file.log" –

+0

यदि आप क्रॉस-प्लेटफ़ॉर्म स्क्रिप्ट लिखते हैं तो '-i' के उपयोग पर सावधान रहें मैकोज़ और लिनक्स पर अलग। – bfontaine

27

अंतिम पंक्ति के बिना फ़ाइल सामग्री प्राप्त करने के लिए, आप उपयोग कर सकते

head -n-1 logfile.log 

(मुझे यकीन है कि यह हर जगह समर्थित है नहीं कर रहा हूँ)

या

sed '$d' logfile.log 
+0

Perfecto !!!! अच्छा एक – Satish

+1

sed एक पूरी तरह से काम करता है! $ d वह आदेश है जो अंतिम पंक्ति से पहले छोड़ दिया गया है, यही कारण है कि यह अंतिम पंक्ति को छोड़ सकता है! Https://www.gnu.org/software/sed/manual/sed.html देखें। – nothize

15

जो भी आप चाहते हैं फ़ाइल को पूरी तरह से फ़ाइल को पढ़ने के बिना अंतिम पंक्ति से ठीक पहले फ़ाइल को छोटा कर दें।

truncate -s -"$(tail -n1 file | wc -c)" file 

यह मानते हुए कि फ़ाइल वर्तमान में लिखी नहीं जा रही है।

ट्रंकेट जीएनयू कोर्यूटिल्स का हिस्सा है (इसलिए आमतौर पर हाल ही में लिनक्स वितरण पर पाया जाता है) और यह मानकीकृत यूनिक्स या POSIX कमांड नहीं है। फाइलों को छोटा करने के लिए कई "डीडी" कार्यान्वयन का भी उपयोग किया जा सकता है।

+0

'tail' +' truncate' का उपयोग करना वास्तव में एक अधिक कुशल समाधान होगा।स्वाभाविक रूप से, ओपी को अंतिम पंक्ति 'पूंछ-एन' की सामग्री को पुनर्प्राप्त करने की अनुमति देने के लिए अलग से कहा जाना चाहिए और एक var में संग्रहीत किया जाना चाहिए। फिर आप छंटनी के आकार के रूप में '$ {# VAR} + 1' का उपयोग कर सकते हैं। –

+0

प्रस्तावित परिवर्तनों के साथ एक [विकी उत्तर] (http://stackoverflow.com/questions/12176492/shell-delete-the-last-line-of-a-huge-text-log-file/12176634#12176634) जोड़ा गया। –

+3

पूंछ/डब्ल्यूसी कॉम्बो से पहले एक अतिरिक्त प्रतीत होता है। साथ ही, आप '-r' विकल्प का उपयोग कर सकते हैं (दी गई फ़ाइल के आकार का उपयोग करें) यहां:' truncate -r <(tail -n1 फ़ाइल) फ़ाइल' अगर आपको बैशिज्म नहीं है। – chepner

संबंधित मुद्दे