ट्रे का उपयोग करते हुए अजीब व्यवहार


10

मेरे पास एक विशेष सर्वर है जो tr का उपयोग करते समय अजीब व्यवहार प्रदर्शित कर रहा है। यहाँ एक कार्यशील सर्वर से एक उदाहरण दिया गया है:

-bash-3.2$ echo "abcdefghijklmnopqrstuvwxyz1234567890"|tr -d [a-z]
1234567890
-bash-3.2$

यह मेरे लिए एकदम सही समझ में आता है।

यह, हालांकि, 'विशेष' सर्वर से है:

[root@host~]# echo "abcdefghijklmnopqrstuvwxyz1234567890"|tr -d [a-z]
abcdefghijklmnpqrstuvwxyz1234567890

जैसा कि आप देख सकते हैं, सभी निचले मामले वर्णों को हटाने में विफल रहता है। लेकिन, यह 'ओ' अक्षर को हटा दिया है

दिलचस्प हिस्सा निम्नलिखित दो उदाहरण हैं, जो मेरे लिए कोई मायने नहीं रखते हैं:

[root@host~]# echo "abcdefghijklmnopqrstuvwxyz1234567890"|tr -d [a-n]
opqrstuvwxyz1234567890
[root@host~]# echo "abcdefghijklmnopqrstuvwxyz1234567890"|tr -d [a-o]
abcdefghijklmnpqrstuvwxyz1234567890
[root@host~]#

(फिर से, अंतिम उदाहरण में 'ओ' हटा दिया गया है)

क्या किसी को कुछ भी पता नहीं है कि यहां क्या चल रहा है? मैं किसी भी अन्य लिनक्स बॉक्स पर पुन: पेश नहीं कर सकता जो मैं उपयोग कर रहा हूं।


5
स्पर्शोन्मुख रूप से संबंधित: trपर्वतमाला बिना संलग्नक के लिखी गई हैं [...]। तो tr -d '[a-z]'मारेंगे a-z, और चरित्र भी [और ]tr -d a-zकेवल पत्रों को मारने के लिए उपयोग करें a-z
सातु कटुरा

जवाबों:


24

आपके पास oवर्तमान निर्देशिका में एक फ़ाइल है

foo> ls
foo> echo "abcdefghijklmnopqrstuvwxyz1234567890"|tr -d [a-z]
1234567890
foo> touch o
foo> echo "abcdefghijklmnopqrstuvwxyz1234567890"|tr -d [a-z]
abcdefghijklmnpqrstuvwxyz1234567890

[a-z]यदि मिलान पाया जाता है तो शेल स्ट्रिंग का विस्तार करेगा ।

इसे पथनाम विस्तार कहा जाता है, के अनुसार man bash

Pathname विस्तार
शब्द विभाजन के बाद, जब तक -f विकल्प सेट नहीं किया गया हो, तो bash प्रत्येक शब्द को *, और, और [अक्षर के लिए स्कैन करता है। ... (...)

बैश विस्तार प्रदर्शन करेंगे।

[...] संलग्न पात्रों में से किसी एक से मेल खाता है।


@ क्रिस आप खोल के विस्तार की जाँच कर सकते हैं उदाहरण के लिए उपयोग कर echo: touch o ; echo tr -d [a-z]यह देता है:tr -d o
पाब्लॉक

8

क्या हो रहा है

खोल (मार) तर्क देखता है [a-z]। यह एक वाइल्डकार्ड पैटर्न (एक ग्लोब ) है, जो किसी भी निचले अक्षर से मेल खाता है। इसलिए शेल एक फ़ाइल नाम के लिए दिखता है जो इस पैटर्न से मेल खाता है। तीन मामले हैं:

  • वर्तमान निर्देशिका की किसी भी फ़ाइल में एक नाम नहीं है जो एक एकल लोअरकेस अक्षर है। फिर शेल वाइल्डकार्ड पैटर्न को अपरिवर्तित छोड़ देता है, और trतर्कों को देखता है -dऔर [a-z]। यह आपकी अधिकांश मशीनों पर होता है।
  • वर्तमान निर्देशिका में एक एकल फ़ाइल में एक नाम है जो एकल लोअरकेस अक्षर है। तब शेल इस फ़ाइल नाम के पैटर्न का विस्तार करता है, और trतर्कों -dऔर फ़ाइल नाम को देखता है । यह सर्वर पर होता है, और मेल खाने वाली फ़ाइल को कहा जाता है oक्योंकि हम देख सकते हैं कि trपत्र को हटा दिया गया है o
  • वर्तमान निर्देशिका में दो या अधिक फ़ाइलों में एक नाम है जो एकल लोअरकेस अक्षर है। तब शेल फ़ाइल नामों के मिलान की सूची में पैटर्न का विस्तार करता है, और trतीन या अधिक तर्क देखता है: -dऔर फ़ाइल नाम। चूंकि trएक के बाद एक तर्क की उम्मीद है -d, यह शिकायत करेगा।

आपको क्या करना चाहिए था

यदि कमांड के तर्क में विशेष वर्ण हैं, तो आपको उनसे बचना चाहिए। तर्क को एकल उद्धरणों में रखें '…'(यह सबसे सरल तरीका है, अन्य हैं)। सिंगल कोट्स के अंदर, सभी कैरेक्टर अपने लिए सिंगल कोटे को छोड़कर खुद के लिए खड़े होते हैं। यदि तर्क के अंदर एक भी उद्धरण है, तो इसे बदलें'\''

tr -d '[a-z]'

हालांकि ध्यान दें कि यह अभी भी संभवतः वह नहीं है जो आप का मतलब है! यह trलोअरकेस अक्षर और वर्ग कोष्ठक को हटाने के लिए कहता है। यह समतुल्य अक्षरों को हटाने के लिए tr -d ']a-z[', के बराबर है tr '[]a-z', का उपयोग करें

tr -d a-z

तर्क trएक वर्ण सेट है। आप यह दर्शाने के लिए कि यह एक कैरेक्टर सेट है, एक नियमित अभिव्यक्ति या वाइल्डकार्ड पैटर्न में सेट किए गए वर्ण के चारों ओर कोष्ठक लगाते हैं। लेकिन trएक समय में एक ही चरित्र पर काम करता है। इसके कमांड लाइन तर्क हैं कि आप कोष्ठक के अंदर क्या रखेंगे

आपको वर्ण वर्गों को इंगित करने के लिए कोष्ठक की आवश्यकता है । एक नियमित अभिव्यक्ति में, आप वर्ण वर्ग को इंगित करने के लिए कोष्ठक के अंदर कोष्ठक का उपयोग करते हैं, उदाहरण [[:lower:]]*के लिए लोअरकेस अक्षरों की [[:lower:]_]*किसी भी संख्या से मेल खाता है , किसी भी लोअरकेस अक्षर से मेल खाता है और अंडरस्कोर करता है। के तर्क में tr, आपको इसके आसपास के कोष्ठक के बिना सेट की आवश्यकता होती है, इसलिए tr -d '[:lower:]'लोअरकेस अक्षर को tr -d '[:lower:]_'हटाता है , लोअरकेस अक्षर को हटाता है और अंडरस्कोर, आदि।

Some कुछ स्थानों में यह अन्य पात्रों से मेल खा सकता है


1
ध्यान दें कि सोलारिस 10 (और अन्य प्राचीन SysV आधारित यूनियनों) पर, आपको इसकी आवश्यकता tr -d '[a-z]'है /usr/bin/tr। के साथ /usr/xpg4/bin/tr, tr -d a-zकाम करता है लेकिन tr -d '[a-z]'[ही हटाता है ]
स्टीफन चेजलस

1
/usr/xpg4/bin/tr -d '[a-z]'नहीं हटाना [और न ही ]जाहिरा तौर पर Solaris 11 में तय किया गया था
स्टीफन चेज़लस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.