Txt फ़ाइल में sed / awk / grep कमांड के साथ मान संपादित करें


9

5 साल के लिए, मैं एक मौसम स्टेशन ला क्रॉस्स WS2350 का उपयोग करता हूं। मौसम केंद्र द्वारा उपलब्ध कराए गए डेटा को RPI पर ओपन 2300 के साथ संसाधित किया जाता है। यह बहुत अच्छा काम करता है। हालांकि, तापमान डेटा गलत है (सेंसर)। तापमान डेटा 1 ° C कम है।

चूंकि मैं सेंसर को कैलिब्रेट नहीं कर सकता हूं, मैं मौसम स्टेशन से निकाली गई फ़ाइल से तापमान मान को बदलना चाहता हूं।

इस पाठ फ़ाइल (current.txt) में शामिल हैं:

Date 2016-Dec-03
Time 10:30:29
Ti 11.9
Timin 11.6
Timax 27.7
TTin 10:34
DTimin 2016-01-19
TTimax 00:44
DTimax 2016-08-28
To -2.4
Tomin -4.8
Tomax 37.4
TTomin 06:46
DTomin 2016-02-18
TTomax 16:13
DTomax 2016-07-19
...

मैं "To", "Tomin", "Tomax" के मानों में +1 जोड़ना चाहता हूं और सही मानों के साथ पाठ फ़ाइल को अधिलेखित करता हूं।

Sed और awk कमांड देखने के बाद, मुझे एहसास हुआ कि मैं आउटडेटेड हूं। क्या कोई मेरा मार्गदर्शन कर सकता है? धन्यवाद

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

मैं एक और फाइल भूल गया: ws2308.log हर 15 मिनट में एक नई लाइन ws2308.log फाइल में जोड़ी जाती है:

...
20161203150600 2016-Dec-03 15:06:00 11.8 -1.1 -3.2 65 87 0.0 157.5 SSE -1.1 569.80 1015.700 
20161203152100 2016-Dec-03 15:21:00 12.3 -1.1 -3.2 64 87 0.0 157.5 SSE -1.1 569.80 1015.600 
20161203153600 2016-Dec-03 15:36:00 12.2 -1.2 -3.3 64 87 0.0 135.0 SE -1.2 569.80 1015.700 

संशोधित किया जाने वाला मान 5 वां क्षेत्र है (पहला -1.2)

यह भी आवश्यक है कि अंतिम पंक्ति पर, तापमान का मान 1 से बढ़ा हुआ हो और अंतिम पंक्ति को सही मान से अधिलेखित कर दे। केवल अंतिम पंक्ति को प्रोग्राम php द्वारा ध्यान में रखा जाएगा जो एक ग्राफ में परिणाम प्रदर्शित करने की अनुमति देता है।

धन्यवाद

जवाबों:


12

यहाँ प्रक्रिया के लिए थोड़ा और मुहावरेदार AWK संस्करण है current.txt( स्टीव का दूसरा उत्तर और भी अधिक मुहावरेदार है)!)

awk '/^To(|min|max) / { print $1, $2 + 1; next } 1' current.txt

यह लाइनों के साथ शुरू होता है To, जिसके बाद कुछ भी नहीं है min, या max, और उसके बाद एक स्थान है; मिलान लाइनों के लिए यह पहले फ़ील्ड और दूसरे फ़ील्ड को प्रिंट करता है, इंक्रीमेंट किया जाता है, डिफ़ॉल्ट आउटपुट फ़ील्ड सेपरेटर (स्पेस) द्वारा अलग किया जाता है। फिर यह अगली पंक्ति में जाता है। अन्य सभी पंक्तियाँ ( 1-AWK में इसके लिए एक शॉर्टकट है) के रूप में मुद्रित होती हैं ।

ध्यान दें कि नए मानों के साथ फ़ाइल को अधिलेखित करना शायद एक अच्छा विचार नहीं है: आपको पता नहीं होगा कि क्या मानों को सही किया गया है या नहीं ... यदि आप हर बार डिवाइस से फ़ाइल को पुनर्प्राप्त करते हैं तो यह लागू नहीं होता है।

एक ही तर्क पर लागू होता है ws2308.log, तो चलो इसे हर बार पूरी तरह से संसाधित करते हैं:

$ awk 'NF >= 5 { $5 = $5 + 1 } 1' ws2308.log
20161203150600 2016-Dec-03 15:06:00 11.8 -0.1 -3.2 65 87 0.0 157.5 SSE -1.1 569.80 1015.700
20161203152100 2016-Dec-03 15:21:00 12.3 -0.1 -3.2 64 87 0.0 157.5 SSE -1.1 569.80 1015.600
20161203153600 2016-Dec-03 15:36:00 12.2 -0.2 -3.3 64 87 0.0 135.0 SE -1.2 569.80 1015.700

यदि आप केवल अंतिम पंक्ति चाहते हैं:

$ awk 'NF >= 5 { $5 = $5 + 1; lastline = $0 } END { print lastline }' ws2308.log
20161203153600 2016-Dec-03 15:36:00 12.2 -0.2 -3.3 64 87 0.0 135.0 SE -1.2 569.80 1015.700

या यदि आप फ़ाइल को केवल अंतिम पंक्ति के साथ बदलना चाहते हैं :

$ awk 'length(prevline) > 0 { print prevline } NF >= 5 { prevline = $0; $5 = $5 + 1; lastline = $0 } END { print lastline }' ws2308.log
20161203150600 2016-Dec-03 15:06:00 11.8 -1.1 -3.2 65 87 0.0 157.5 SSE -1.1 569.80 1015.700 
20161203152100 2016-Dec-03 15:21:00 12.3 -1.1 -3.2 64 87 0.0 157.5 SSE -1.1 569.80 1015.600 
20161203153600 2016-Dec-03 15:36:00 12.2 -0.2 -3.3 64 87 0.0 135.0 SE -1.2 569.80 1015.700

10

यहाँ एक उपाय है। किसी भी लाइन के लिए जो "To", "Tomin" या "Tomax" के साथ शुरू होती है, उसके बाद पहली फील्ड को प्रिंट करती है और फिर दूसरी फील्ड को इंक्रीमेंट करती है। अन्यथा, पूरी लाइन को प्रिंट करें।

$ awk '{if(/^(To|Tomin|Tomax) /){print $1 " " $2+1}else{print $0}}' w.txt
Date 2016-Dec-03
Time 10:30:29
Ti 11.9
Timin 11.6
Timax 27.7
TTin 10:34
DTimin 2016-01-19
TTimax 00:44
DTimax 2016-08-28
To -1.4
Tomin -3.8
Tomax 38.4
TTomin 06:46
DTomin 2016-02-18
TTomax 16:13
DTomax 2016-07-19
$

5

एक और दृष्टिकोण, थोड़ा गोल्फ

$ awk '/^To/{$2++}1' w.txt
Date 2016-Dec-03
Time 10:30:29
Ti 11.9
Timin 11.6
Timax 27.7
TTin 10:34
DTimin 2016-01-19
TTimax 00:44
DTimax 2016-08-28
To -1.4
Tomin -3.8
Tomax 38.4
TTomin 06:46
DTomin 2016-02-18
TTomax 16:13
DTomax 2016-07-19
$

3
नीस (इसलिए +1), लेकिन आप इसे केवल अपने मौजूदा उत्तर को संपादित कर सकते हैं!
स्टीफन किट

@Scott -iपर awkकहते हैं एक फ़ाइल, यह ऐसा कुछ नहीं शामिल sedकी -iविकल्प।
स्टीफन किट

@StephenKitt: D'oh! मैं जानता था कि।
स्कॉट

5

एक पर्ल दृष्टिकोण:

perl -i -ape '/^To/ && s/$F[1]/$F[1]+1/e' file

-iयह मूल फ़ाइल अधिलेखित, तो यह कुछ भी नहीं प्रिंट आउट, यह फ़ाइल सीधे बदल जाएगा बनाता है।

-aबनाता है perlकी तरह काम करते awkwhitesapce पर अपने इनपुट (या कुछ और के द्वारा दिए गए, बंटवारे -Fसरणी में) @F। इसलिए, दूसरा क्षेत्र होगा $F[1]क्योंकि सरणियों की गणना 0. पर शुरू होती है। लिपि इसलिए दूसरे क्षेत्र को अपने साथ बढ़े हुए लाइनों के साथ एक के बाद एक के साथ प्रतिस्थापित करेगी To


2

यह काम करेगा:

  1. पहले सभी लाइनों के माध्यम से जाना जाएगा
  2. फिर पहले आइटम की जांच करें और जांचें कि क्या आप चाहते हैं कि यह मेल खाता है।
  3. फिर, यदि यह मेल खाता है, तो इसे प्रिंट करें और पंक्ति में अगले आइटम पर +1 जोड़ें
  4. और बस इसे प्रिंट करें और अगले आइटम को प्रिंट करें

    awk '{
        for(i=1;i<=NF;i++) {
                t+=$i;if(i==1){
                        if($i=="To" ||$i=="Tomin" ||$i=="Tomax"  ){
                                printf  "%s ",$i;
                                print $(i+1)+1;}
    
                        else{
                                print $0
                                }
                        }
                        };
        }' current.txt
    

आउटपुट

Date 2016-Dec-03
Time 10:30:29
Ti 11.9
Timin 11.6
Timax 27.7
TTin 10:34
DTimin 2016-01-19
TTimax 00:44
DTimax 2016-08-28
To -1.4
Tomin -3.8
Tomax 38.4
TTomin 06:46
DTomin 2016-02-18
TTomax 16:13
DTomax 2016-07-19
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.