awk एक ही बार में कई वेरिएबल्स को असाइन करें


9

मैं एक स्ट्रिंग से दो संख्यात्मक मूल्यों को खींचने की कोशिश कर रहा हूं और उन्हें चर का उपयोग करके असाइन कर रहा हूं awk( gawkजो मैं विशेष रूप से उपयोग कर रहा हूं)। मैं बड़े और छोटे संस्करण संख्याओं को tmux संस्करण स्ट्रिंग से awkचर में खींचना चाहता हूं , जैसे:

  • इनपुट tmux 2.8:; maj == 2तथाmin == 8
  • इनपुट tmux 1.9a:; maj == 1तथाmin == 9
  • इनपुट tmux 2.10:; maj == 2तथाmin == 10

मेरा इनपुट tmux -Vस्टड पर से माना जाता है , मैं वर्तमान में निम्नलिखित है:

tmux -V | awk '{
                  maj = +gensub(/([0-9]+)\..*/, "\\1", "g", $2);
                  min = +gensub(/.*\.([0-9]+).*/, "\\1", "g", $2);
                  # ...do something with maj and min...
               }'

यह काम करता है, लेकिन tmux पता के बहुत से उपयोगकर्ताओं, का उपयोग कर के रूप में if-shellमें .tmux.confफ़ाइल को आसानी से करने के लिए नेतृत्व कर सकते हैं (जहां मैं इस सामान का उपयोग करने की उम्मीद है) वास्तव में , कॉन्फ़िग फ़ाइल में लंबी लाइनें तो मैं वहाँ इन दो चर गठबंधन करने के लिए कोई तरीका है सोच रहा हूँ अंतरिक्ष को बचाने के लिए एक कथन में असाइनमेंट ... या इनपुट से इन दो चर को चमकाने और अंतरिक्ष को बचाने का कोई अन्य तरीका।

मैं कुछ ऐसा सोच रहा हूँ:

awk '{ maj, min = +gensub(/([0-9]+)\.([0-9]+).*/, "\\1 \\2", "g", $2); }'

... अजगर की तरह, लेकिन उस विशेष वाक्यविन्यास में मौजूद नहीं है awk। क्या ऐसा कुछ और संभव है?

ध्यान दें कि पठनीयता वास्तव में एक चिंता का विषय नहीं है, बस लंबाई है।

जवाबों:


9

ध्यान दें कि gensubयह एक gawkविस्तार है, यह किसी अन्य awkकार्यान्वयन के साथ काम नहीं करेगा । यह भी ध्यान रखें कि +एकात्मक ऑपरेटर सभी awkकार्यान्वयनों में संख्यात्मक रूपांतरण को मजबूर नहीं करता है, + 0और अधिक पोर्टेबल है।

यहाँ आप कर सकते हैं:

tmux -V | awk -F '[ .]' '{maj = $2+0; min = $3+0; print maj, min}'

यदि आपको GNU awkएक्सटेंशन का उपयोग करने में कोई आपत्ति नहीं है , तो आप यह भी कर सकते हैं:

tmux -V | awk -v FPAT='[0-9]+' '{maj = $1; min = $2; print maj, min}'

संगतता पर अतिरिक्त स्पष्टीकरण के लिए धन्यवाद!
विलापएक्स

13

चूंकि आप GNU awk का उपयोग कर रहे हैं, आप match()कई कैप्चरिंग समूहों को स्टोर करने के लिए 3-arg फॉर्म का उपयोग कर सकते हैं :

awk '
    match($0, /([0-9]+)\.([0-9]+)/, m) {maj=m[1]; min=m[2]; print maj, min}
' <<END
tmux 2.8
tmux 1.9a
tmux 2.10
END
2 8
1 9
2 10

https://www.gnu.org/software/gawk/manual/html_node/String-Functions.html


5

आप संस्करण को एक सरणी में विभाजित कर सकते हैं:

awk '{ split($2, ver, /[.a-z]/) }'

तो का उपयोग ver[1]करने के बजाय maj, ver[2]की बजाय min

a-zविभाजक में जोड़ना किसी भी लोअरकेस अक्षर को संस्करण संख्या से हटा देता है। (अन्य समाधान बेहतर हैं क्योंकि वे स्पष्ट रूप से संख्याएँ निकालते हैं।)


3

एक अन्य उपयोगकर्ता ने इस उत्तर को पोस्ट किया, और इसे बाद में हटा दिया गया। मुझे लगा कि यह उपयोगी है:

split()फ़ंक्शन का उपयोग करके , संस्करण स्ट्रिंग को एक सरणी में विभाजित करें ver, फिर क्रमशः पहुंच ver[1]और ver[2]बजाय, majऔर min(या बस उन चर में मूल्यों को संग्रहीत करें):

tmux -V | awk '{ split($2, ver, /[.a-z]/); print ver[1], ver[2] }'

यहां प्लस यह है कि split()कोई gawkएक्सटेंशन नहीं है (हालांकि इसका वैकल्पिक चौथा तर्क sepsहै)।


+1, लेकिन स्ट्रिंग फ़ंक्शन /[.a-z]/के तीसरे (फ़ील्ड सेपरेशन) तर्क के रूप में उपयोग क्यों split, इसके बजाय बस "."?
Cbhihe

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