awk sed अगर कथन


9

मैं शुरुआत में 0 जोड़ने की कोशिश कर रहा हूं, अगर कोई "है।" उस पंक्ति के दूसरे वर्ण पर। मैं इन दोनों को मिला नहीं सकता;

awk '{ print substr( $0, 2, 1 ) }' file.txt 

दूसरा चरित्र दिखा रहा है

sed -ie "s/.\{0\}/0/" file.txt

शुरुआत में एक शून्य जोड़ना।

एक "यदि दूसरा वर्ण एक बिंदु है" होना चाहिए।

नमूना फ़ाइल:

1.02.2017 23:40:00
10.02.2017 23:40:00

अंतिम:

01.02.2017 23:40:00
10.02.2017 23:40:00

जवाबों:


12

हम sedया तो awkसमस्या का पूरी तरह से समाधान करने के लिए या तो उपयोग कर सकते हैं ।


के साथ sed:

$ sed 's/^.\./0&/' file.txt

जब &प्रतिस्थापन कमांड ( s) के प्रतिस्थापन भाग में होता है , तो इसे इनपुट लाइन के भाग तक विस्तारित किया जाएगा जो कमांड के पैटर्न भाग से मेल खाता है।

नियमित अभिव्यक्ति का ^.\.अर्थ है " एक शाब्दिक बिंदु ( ) के बाद शुरू होने वाली (सभी ^) एक मनमाना चरित्र ( .) के साथ शुरू होने वाली रेखाओं से मेल खाना\. "।

यदि रेखा है 1.02.2017 23:40:00, तो पैटर्न मेल खाएगा, और लाइन की शुरुआत में 1.प्रतिस्थापित किया जाएगा 01.


के साथ awk:

awkप्रश्न में आंशिक कोड पर बिल्डिंग ...

जैसा कि कहा गया है, इनपुट की प्रत्येक पंक्ति के दूसरे वर्ण को प्रिंट करें:

$ awk '{ print substr($0, 2, 1) }' file.txt

हम इस तथ्य का उपयोग कर सकते हैं कि substr($0, 2, 1)दूसरा चरित्र लौटाता है और शर्त के रूप में उपयोग करता है:

$ awk 'substr($0, 2, 1) == "." { ... }' file.txt

जो { ... }कोड में जाता है वह प्रीपेंड करता है $0, जो कि वर्तमान लाइन की सामग्री है, एक शून्य के साथ यदि पूर्ववर्ती स्थिति सत्य है:

$ awk 'substr($0, 2, 1) == "." { $0 = "0" $0 }' file.txt

फिर हमें केवल यह सुनिश्चित करने की आवश्यकता है कि सभी लाइनें मुद्रित हैं:

$ awk 'substr($0, 2, 1) == "." { $0 = "0" $0 } { print }' file.txt

स्थिति substr($0, 2, 1) == "."को निश्चित रूप से एक नियमित अभिव्यक्ति में बदला जा सकता है (हम ठीक उसी अभिव्यक्ति का उपयोग करते हैं जैसा हमने sedसमाधान में किया था ):

$ awk '/^.\./ { $0 = "0" $0 } { print }' file.txt

कुछ लोग जो सोचते हैं कि "कम हमेशा बेहतर होता है" वह लिखते हैं

$ awk '/^.\./ { $0 = "0" $0 } 1' file.txt

(और शायद भी सबसे रिक्त स्थान निकालें: awk '/^.\./{$0="0"$0}1' file.txt)


1
+1 आपका आखिरी AWK उदाहरण या आपका sed उदाहरण ऐसा करने के सही तरीके हैं। ध्यान दें, स्पष्टता के लिए, कि यह केवल एक या दूसरा होगा।
अगली सूचना तक रोक दिया गया।

मेरी राय में "सही" दृष्टिकोण (जो रिक्त स्थान के साथ बेला नहीं करता है और जो वैसे भी हल्का वजन है) आपका अंतिम संस्करण है sed 's/^.\./0&/' file.txt। मुझे लगता है कि आपको इस उत्तर की शुरुआत में रखना चाहिए। फिर भी, +1।
वाइल्डकार्ड

1
@Wildcard हम कृपया करने के लिए लक्ष्य।
Kusalananda

5

Sed के साथ:

sed -e "/^.\./s/^/0/" file.txt 

/^.\./रेखा के प्रारंभ में पैटर्न किसी भी वर्ण और शाब्दिक बिंदु के लिए दिखता है ^, और यदि वह मेल खाता है, तो sसर्वव्यापी है जो एक शून्य के साथ पंक्ति की शुरुआत करता है, प्रभावी रूप से शून्य को शुरुआत में जोड़ता है।

सिड एक्सप्रेसोइन s/.\{0\}/0/कुछ हद तक अजीब है, यह किसी भी चीज़ की शून्य या अधिक प्रतियों से मेल खाता है और एक शून्य के साथ बदल देता है। पैटर्न निश्चित रूप से स्ट्रिंग की हर स्थिति में मेल खाएगा, लेकिन चूंकि s///केवल पहला मैच बदलता है, यह आपके इच्छित उद्देश्य के अनुसार काम करता है। एक विचित्र तरीका यह करना है, यद्यपि।


या awk के साथ, एक समान रेगेक्स लाइन से मेल खाने के लिए काम करेगा, लेकिन हम उपयोग कर सकते हैं substr:

awk 'substr($0, 2, 1) == "." {$0 = "0" $0} 1' file.txt 

हम पहले परीक्षण करते हैं कि यदि दूसरा वर्ण एक डॉट है, तो यदि ऐसा है तो लाइन के सामने एक शून्य जोड़ें। अंतिम किसी भी संशोधन के बाद लाइन को प्रिंट करने की डिफ़ॉल्ट कार्रवाई को आमंत्रित करता है।


4

आपने कहा कि अजीब और सेड है, लेकिन ऐसा लगता है जैसे आप एक तारीख को प्रारूपित करने की कोशिश कर रहे हैं और इसके लिए मैं dateकमांड का उपयोग करूंगा । उदाहरण के लिए:

echo '1.2.2017 23:40:00' | sed 's/\./\//g' | xargs -0 date '+%m.%d.%Y %T' -d

उत्पादन होगा

01.02.2017 23:40:00

sedबीच में आदेश में निवेश के लिए स्लैश करने के लिए अवधि में परिवर्तन date -d। प्रारूप विकल्प आपके इच्छित किसी भी प्रारूप में आउटपुट की अनुमति देता है। %mविशेष इच्छा शून्य-पैड में महीने है, जो है यह क्या लगता है आपके पास करने के लिए कोशिश कर रहे हैं।

कुसलानंद बताते हैं:

और भी अधिक कॉम्पैक्ट (GNU दिनांक और बैश): date -f <(tr '.' '/' <dates.in) '+%m.%d.%Y %T'


2
अच्छा पकड़ा! इससे भी अधिक कॉम्पैक्ट (जीएनयू तारीख और बैश):date -f <(tr '.' '/' <dates.in) '+%m.%d.%Y %T'
Kusalananda

: जब भी मैं अपने पैटर्न में स्लैश, लेकिन कोई पाइप्स है s|\.|/|g। अन्यथा, जैसा कि ऊपर उल्लेख किया गया है: नाइस कैच, +1
एलेक्स स्ट्रैगिज

2

अन्य उत्तरों में प्रस्तुत की तुलना में एक अलग रणनीति: आप उपयोग कर सकते हैं "।" क्षेत्र विभाजक के रूप में।

awk -F. '$1 < 10 {printf "0"} {print}' /tmp/in.txt

आप इसे गोल्फ कर सकते हैं:

awk -F. '$1<10{printf "0"}1' /tmp/in.txt

Sed के लिए, एक छोटी कमांड होती है, जिसे दूसरे (महान) उत्तर में प्रस्तुत किया जाता है।


1
वैकल्पिक:awk -F. '{print ($1<10?0$0:$0)}' file
जॉर्ज वासिलिउ

1

Sed के साथ यह हो सकता है

sed 's/^\(.\)\.\(.*\)/0\1.\2/'

यह ^लाइन की शुरुआत में एंकर का उपयोग करेगा , फिर समूह में किसी भी एकल वर्ण को कैप्चर करेगा, उसके बाद शाब्दिक .और फिर कुछ भी। यदि हम मिलान करते हैं कि हम एक प्रिंट करते हैं 0, तो हमारा पहला कैप्चर ग्रुप (लाइन की शुरुआत में कैरेक्टर), फिर एक .दूसरा हमारा कैप्चर ग्रुप (बाकी लाइन)


यह बिल्कुल भी जरूरी नहीं है कि कोई भी कब्जा करे। &आपका दोस्त है। कुसलानंद का सेड उदाहरण देखें।
अगली सूचना तक रोक दिया गया।

@DennisWilliamson आवश्यक नहीं है, लेकिन दिए गए अन्य उदाहरण पहले से ही यह दिखा रहे हैं sedकि इसकी एक और विशेषता अन्य स्थितियों में उपयोगी हो सकती है, न कि केवल इस विशिष्ट समस्या
एरिक रेनॉफ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.