यह कैसे कहें कि एक स्ट्रिंग में एक नया चरित्र है और यदि हां, तो इसे हटा दें


9

मेरे पास एक स्ट्रिंग है जो कुछ ऑपरेशन का परिणाम है जिसका मेरे पास कोई नियंत्रण नहीं है। जब मैं इस चर का उपयोग करके प्रिंट करता हूं echo, मुझे मिलता है:

echo $myvar
hello

हालांकि, जब मैं करता हूं

if [ $myvar = "hello" ]; then
    echo they are equal
else
    echo they are not equal
fi

मुझे हमेशा लगता है कि वे समान नहीं हैं। मुझे संदेह है कि यह एक newlineचरित्र के कारण है।

स्ट्रिंग भी अजीब व्यवहार करती है। जब मैं करता हूं:

newVAR="this is my var twice: "$myvar$myvar
echo $newVAR

मुझे मिला:

hellois my var twice: hello

मैं कैसे जांच सकता हूं कि क्या यह वास्तव में ए के कारण है newline, यदि हां, तो इसे हटा दें?


1
बैश में आप printf '%q\n' "$string"किसी भी स्ट्रिंग का एक बचा हुआ संस्करण प्राप्त कर सकते हैं । उदाहरण के लिए: printf '%q\n' 'foo\n'-> foo\\n; printf '%q\n' $'foo\n'->$'foo\n'
l0b0

1
आप अपने किसी भी चर के विस्तार का हवाला नहीं दे रहे हैं। यदि उनके पास कोई अनुगामी व्हाट्सएप होता, तो आप इसे नहीं देखते echo $fooecho "$foo"इसके बजाय करो ।
पीटर कॉर्ड्स

जवाबों:


9

समस्या यह है कि आपके पास एक एम्बेडेड कैरिज-रिटर्न (सीआर \r) है। यह टर्मिनल पाठ-प्रविष्टि बिंदु को उस रेखा के प्रारंभ में वापस किक करने का कारण बनता है जिसे वह प्रिंट कर रहा है। यही कारण है कि आप $newVARउदाहरण के रूप में लाइन की शुरुआत में 'हैलो' देख रहे हैं - sed -n lअनपेक्षित वर्णों (और लाइन के अंत) का एक पठनीय दृश्य प्रदर्शित करता है।

var=ab$'\r'c ; echo "$var";  printf %s "$var" | sed -n l
# output:
cb
ab\rc$

आप इसके लिए एक साधारण bash कंडीशन चेक कर सकते हैं:

[[ $var == *$'\r'* ]] && echo yes || echo no
# output:
yes

आप परीक्षण को जोड़ सकते हैं और एक चरण में \r(एस) के लिए परीक्षण करके और उन्हें हटाकर ठीक कर सकते हैं :

fix="${var//$'\r'/}"; echo "$var"; echo "$fix"
# output:
cb
abc

ठीक उपयोग करता शैल पैरामीटर विस्तार । ऊपर इस्तेमाल किया गया विशेष रूप आपके प्रोवेरेटेड पैटर्न के आधार पर सबस्ट्रिंग को बदलने के लिए है: ${parameter/pattern/string}<- यह केवल पहले पाए गए पैटर्न को स्ट्रिंग में स्ट्रिंग * नाम के पैरामीटर के साथ बदलता है । सभी पैटर्नों को बदलने के लिए , आपको बस पहले /को बदलना होगा //


क्या आप अपने अंतिम बिट कोड की व्याख्या कर सकते हैं? fix="....लाइन?
farid99

@ farid99: स्पष्टीकरण में जवाब देने के लिए जोड़ा गया है, नोट स्वयं fixहो सकता varहै - या अक्सर आप बस के रूप में पैरामीटर विस्तार का उपयोग कर सकते हैं- (संभवतः) संशोधित मूल्य को पुन: सौंपने की आवश्यकता के बिना ..
पीटर।

5

आप मार के \rरूप $'\r'में प्रतिनिधित्व कर सकते हैं :

if [ "$myvar" = "hello"$'\r' ]; then
    echo they are equal
else
    echo they are not equal
fi

या अंतिम \rमें काट लें myvar:

if [ "${myvar%$'\r'*}" = "hello" ]; then
    echo they are equal
else
    echo they are not equal
fi

3

उत्सुकता से, कई गोले getoptsमें इस तरह की नौकरी के लिए एक बहुत ही संभावित उम्मीदवार है। यह पहली बार में getoptsस्पष्ट लग सकता है, लेकिन अगर आप समझते हैं कि 'प्राथमिक कार्य को पहचानना और व्याख्या के लिए प्रस्ताव देना है, तो कई निर्दिष्ट एकल वर्ण-पंक्ति विकल्प हैं, जो उसी की एक संक्षिप्त श्रृंखला में मिल सकते हैं, यह थोड़ा शुरू हो सकता है अधिक समझदारी।

bashशेल से प्रदर्शित करने के लिए :

x=$(printf '\n\r%010s\t' hello)
OPTIND=1
while  getopts : na "-$x"
do     printf %q\\n "$OPTARG"
done

$'\n'
$'\r'
\
\
\
\
\
h
e
l
l
o
$'\t'

इस तरह यह कभी-कभी सुविधाजनक हो सकता है getoptsकि इस तरह के मामलों के लिए शेल ऑटो-पायलट के एक प्रकार के रूप में डिस्सैड को संभालने की अनुमति दी जाए। बस बाहर अवांछित बाइट्स w / एक स्क्रीन जब आप ऐसा करते हैं, आप कर सकते हैं caseया [परीक्षण ]करने और अपने स्ट्रिंग बैक अप बाइट 1 से निर्माण:

OPTIND=1 y=$(printf \\n\\r) z=
while  getopts : na "-$x"
do     case $OPTARG in ([!$y])
            z=$z$OPTARG
       esac
done
printf %q\\n "$z"

$'     hello\t'

इस सरल उदाहरण के मामले को देखते हुए - और एक शेल दिया गया है जो पहले से कहीं और वर्णित पैरामीटर विस्तार का समर्थन करता है - कहा विस्तार शायद आपको यहां बेहतर सेवा देगा। लेकिन मुझे लगा कि getoptsइस संदर्भ में आपको इसकी क्षमताओं के बारे में पता नहीं होने के साथ ही एक उल्लेख के लायक भी हो सकता है। निश्चित रूप से जब मुझे इसके बारे में पता चला तो मुझे इसके लिए कई उपयोगी एप्लिकेशन मिले, वैसे भी।


0

हालांकि बैश और अन्य शेल भाषाएं आसान हैं, कभी-कभी एक सही स्क्रिप्टिंग भाषा का उपयोग करना बेहतर होता है - जैसे पर्ल। पर्ल शेल स्क्रिप्ट की जगह ले सकता है जो अन्य भाषाओं जैसे कि sed और awk के साथ-साथ UNIX कमांड को काफी आसानी से कॉल करता है। मैंने यह 20+ साल पहले सीखा था जब C-Shell स्क्रिप्ट लिख रहा था जो बदले में sed, awk, और विभिन्न UNIX कमांड - फोरट्रान कोड को कॉल करने से पहले। पर्ल में मैं करूँगा:

chomp($myvar);   # removes the newline char

if("$myvar" eq "hello")   # string comparison
  {
  print "they are equal\n";
  }
else
  {
  print "they are not equal\n";
  }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.