बैश में अंतिम बिंदु के बाद स्ट्रिंग बदलें


12

मैं एक स्ट्रिंग में निम्नलिखित पैटर्न है (एक आईपी पता):

123.444.888.235

मैं डॉट के बाद अंतिम संख्या को बदलना चाहता हूं 0, इसलिए यह बन जाता है:

123.444.888.0

मैं इसे bashया अन्य शेल स्क्रिप्ट भाषा में कैसे कर सकता हूं ?


1
वो तार कहाँ हैं? एक बैश चर में? एक पाठ फ़ाइल में प्रति पंक्ति एक?
स्टीफन चेज़लस

यह एक चर में है। मुझे खेद है कि मैं इसका उल्लेख करना भूल गया था।
अरी

3
यदि वे IP पते हैं, तो 444 और 888 अमान्य ऑक्टेट मान हैं।
डिजिटल ट्रॉमा

जवाबों:


24

किसी भी POSIX शेल में:

var=123.444.888.235
new_var="${var%.*}.0"

${var%pattern}ksh80 के दशक में एक ऑपरेटर द्वारा शुरू किया गया था, जो मानक shभाषा के लिए POSIX द्वारा मानकीकृत है और अब उस भाषा की व्याख्या करने वाले सभी गोले द्वारा कार्यान्वित किया जाता है bash

${var%pattern}$varसबसे छोटी स्ट्रिंग से छीन की गई सामग्री तक फैल जाती है जो इसके अंत से पैटर्न से मेल खाती है (या उसी तरह $varजैसे कि वह पैटर्न लागू नहीं होता है)। इसलिए ${var%.*}(जहां .*एक पैटर्न है जिसका मतलब है कि किसी भी संख्या में वर्णों के बाद डॉट) $varसही-सबसे के बिना फैलता है .और इसका अनुसरण करता है। इसके विपरीत, ${var%%.*}जहां पैटर्न से मिलान करने वाली सबसे लंबी स्ट्रिंग $varको बाईं ओर के बिना विस्तारित किया जाएगा .और इसके बाद क्या होगा।


क्या है ? ${var%.*}
आवाजें

@ tjt263, कमांड लाइन प्रकार पर man bashऔर एंटर दबाएं, फिर टाइप करें /suffix patternऔर एंटर दबाएं। :)
वाइल्डकार्ड

अपनी पोस्ट के बाद कुछ उद्धरण जोड़े : new_var="${var%.*}.0"... nJoy!।

8

यह काम करना चाहिए।

echo 123.444.888.235 | sed 's/\([0-9]*\.[0-9]*\.[0-9]*\.\)[0-9]*/\10/'

ध्यान दें कि sedप्रतिस्थापन का अंतिम क्षेत्र , \10पहला मिलान पैटर्न ( \1) है, जिसे शाब्दिक शून्य के साथ मिलाया गया है।


5

कुछ तरीके (ये सभी मानते हैं कि आप स्ट्रिंग में संख्याओं के अंतिम सेट को बदलना चाहते हैं):

$ echo 123.444.888.235 | awk -F'.' -vOFS='.' '{$NF=0}1;'
123.444.888.0

यहाँ, इनपुट फील्ड सेपरेटर के रूप में उपयोग करने और आउटपुट फील्ड सेपरेटर के रूप में उपयोग करने के लिए -F'.'कहता awkहै । फिर, हम बस आख़िरी क्षेत्र (सेट 0 करने के लिए) और लाइन प्रिंट ( है "वर्तमान लाइन प्रिंट" के लिए आशुलिपि)।.-vOFS='.'$NF1;awk

$ echo 123.444.888.235 | perl -pe 's/\d+$/0/'
123.444.888.0

-pबताता perlस्क्रिप्ट द्वारा दिए गए आवेदन करने के बाद प्रत्येक इनपुट लाइन मुद्रित करने के लिए -e। स्क्रिप्ट ही एक साधारण प्रतिस्थापन संचालक है जो पंक्ति के अंत में एक या अधिक संख्याओं को प्रतिस्थापित करेगा 0

$ echo 123.444.888.235 | sed 's/[0-9]*$/0/'
123.444.888.0

में एक ही विचार sed, का उपयोग कर [0-9]के बजाय \d


यदि आपकी स्ट्रिंग एक चर में है और आप एक ऐसे शेल का उपयोग करते हैं जो यहां तार का समर्थन करता है (जैसे कि bashया zshउदाहरण के लिए), तो आप ऊपर बदल सकते हैं:

awk -F'.' -vOFS='.' '{$NF=0}1;' <<<$var
perl -pe 's/\d+$/0/' <<<$var
sed 's/[0-9]*$/0/' <<<$var

5

आईपी ​​पते पर नेटमास्क लगाने के लिए सामान्य मामला:

यह देखते हुए कि आपका इनपुट एक आईपी पता है, और यह कि आप उस पते के अंतिम ऑक्टेट की जगह ले रहे हैं .0, तो मुझे लगता है कि आप वास्तव में जो हासिल करने की कोशिश कर रहे हैं वह 255.255.255.0नेटमैक्स का उपयोग करके आईपी पते के नेटवर्क हिस्से की गणना करना है ।

यदि ओटमास्क की लंबाई 8 से विभाज्य है, तो बस जीरो के साथ ओकटेट्स को बदलना ठीक है, लेकिन यह सामान्य मामला नहीं है। यदि आपको कभी भी किसी वैध (सबनेट) नेटमास्क के लिए इस ऑपरेशन को करने की आवश्यकता है, तो आप कुछ इस तरह से कर सकते हैं:

function d2i() {
    echo $(( 0x$( printf "%02x" ${1//./ } ) ))
}

function i2d() {
    h=$( printf "%08X" "$1" )
    echo $(( 0x${h:0:2} )).$(( 0x${h:2:2} )).$(( 0x${h:4:2} )).$(( 0x${h:6:2} ))
}

function ipmask() {
    i2d $(( $( d2i $1 ) & $( d2i $2 ) ))
}

ipmask 123.44.88.235 255.255.255.0     # outputs 123.44.88.0
ipmask 123.44.88.235 255.255.255.240   # outputs 123.44.88.224

यह 3 कार्यों को परिभाषित करता है:

  • d2i() एक आईपी पते (या मुखौटा) के बिंदीदार-दशमलव रूप को एक साधारण पूर्णांक में परिवर्तित करता है
  • i2d() इसके विपरीत - एक साधारण पूर्णांक को एक बिंदीदार दशमलव में परिवर्तित करता है
  • ipmask()बस एक पते के एक बिटवाइज और एक नेटमैस्क की गणना करता है और एक पते के नेटवर्क भाग को देने के लिए। बैश को उम्मीद है कि ऑपरेंड्स &पूर्णांक होंगे।

दो कॉल यह ipmaskदिखाने के लिए कि दो अलग-अलग मास्क के लिए आईपी पते से नेटवर्क की गणना कैसे की जा सकती है।


नोट जैसा कि प्रश्न में कहा गया है, 123.444.888.235एक अमान्य IP पता है। मैंने 123.44.88.235इन उदाहरणों के बजाय उपयोग किया है ।


0

एक वैकल्पिक sedउत्तर:

sed -r 's/(.*\.).*/\10/'

यह सब कुछ अंतिम बिंदु तक समूहित करता है और समूह की सामग्री के साथ पूरी पंक्ति को प्रतिस्थापित करता है। इसके बाद 0.
मैं -r का उपयोग करता है ताकि कोष्ठक से बच सकें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.