\ R का \ n अर्थ के लिए तर्क क्या है?


13

हम सभी जानते हैं कि खोज करते समय, \nन्यूलाइन है और \rकैरिज रिटर्न ( ^M) है, लेकिन जब \rरीप्लेसिंग न्यूलाइन है जबकि \nएक नल बाइट ( ^@) है।

इस विषमता की उत्पत्ति क्या है? यह देखते हुए कि यह व्यवहार है ... अजीब कम से कम कहने के लिए (और काफी उल्टा जब आप पहली बार गलत हो जाते हैं) मुझे उम्मीद है कि कुछ विचित्र ऐतिहासिक कारण है।

(संयोग से, क्या इस व्यवहार को "ठीक" करने और कुछ अधिक सहज ज्ञान प्राप्त करने का कोई तरीका है?

जवाबों:


10

सबसे बुनियादी स्तर पर, पहले से ही खोज के बीच एक विषमता है और भागों को बदलना :substituteक्योंकि पूर्व एक नियमित अभिव्यक्ति है और उत्तरार्द्ध पाठ है, जिसमें विशिष्ट अतिरिक्त एस्केप अनुक्रम हैं । यह सिर्फ आपके द्वारा बताए गए अंतर्ज्ञान से उजागर होता \nहै।

उदाहरण के लिए, विचार करें कि \nखोज में शाब्दिक रूप से मेल नहीं खाता है \n। यह लाइन (EOL) बाइट क्रम के अंत है, जो हो सकता है से मेल खाता है \r, \r\nहै, या बस \nके आधार पर 'fileformat'बफर के।

जहाँ तक \r"ईओल डालने" का अर्थ क्यों किया जाता है, इसके पीछे कुछ इतिहास है। वीआई के पास एक फाइल में एनयूएल बाइट को संभालने का कोई तरीका नहीं था। विम ने एनएल बाइट्स की जगह एनएल बाइट को आंतरिक रूप से बदल दिया (सी स्ट्रिंग्स एनयूएल सीमांकित हैं)।

इस कार्यान्वयन विस्तार के :substituteबाद से व्यवहार में लीक हो गया \nहै, बस उस लाइन के आंतरिक प्रतिनिधित्व में डाला जाता है, जिसका उपयोग एनयूएल बाइट को इंगित करने के लिए किया जाता है। \rएक ईओएल सम्मिलित करता है, दो में आंतरिक रेखा को तोड़ता है। विम वास्तव में ईओएल बाइट्स को मेमोरी में स्टोर नहीं करता है, इसके बजाय (डी) बफर को पढ़ने / लिखने पर उन्हें क्रमबद्ध करता है।

कई लिपियों और कई उपयोगकर्ताओं की मांसपेशियों की मेमोरी को तोड़े बिना अब इसे बदला नहीं जा सकता है। शुक्र है, यह दस्तावेज में है :help sub-replace-special


6

एक NULबाइट सी में एक स्ट्रिंग टर्मिनेटर है, और इस कारण से विम इस कन्वेंशन का उपयोग करता है, जिसे मैनुअल में वर्णित किया गया है :h NL-used-for-Nul:

फ़ाइल में <Nul> अक्षर मेमोरी में <NL> के रूप में संग्रहीत हैं। डिस्प्ले में उन्हें "^ @" के रूप में दिखाया गया है। अनुवाद फ़ाइलों को पढ़ने और लिखने पर किया जाता है। <Nul> को एक खोज पैटर्न से मिलान करने के लिए आप बस CTRL- @ या "CTRL-V 000" दर्ज कर सकते हैं। यह शायद सिर्फ वही है जो आप उम्मीद करते हैं। आंतरिक रूप से चरित्र को खोज पैटर्न में <NL> से बदल दिया जाता है। क्या असामान्य है कि CTRL-V टाइपिंग CTRL-J भी एक <NL> सम्मिलित करता है, इस प्रकार फ़ाइल में एक <Nul> भी खोजता है। {Vi फाइल में <Nul> अक्षर को नहीं संभाल सकता है}

यह अधिवेशन :s/.../.../कमान को सौंप दिया गया है , लेकिन substitute()कार्य के लिए नहीं । \rऔर कॉल \nमें प्रतिस्थापन के तार substitute()अपने मूल अर्थ को बनाए रखते हैं।

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


0

अन्य Vi क्लोन प्रतिस्थापन में समर्थन ( \rया \nवास्तविक बैकस्लैश और पत्र के रूप में) नहीं करते हैं, लेकिन लाइन को दो लाइनों में विभाजित करने के लिए एक वास्तविक ^M( CTRL-V Enter) अर्थ का व्यवहार मानक व्यवहार है :

एक <गाड़ी-वापसी> में प्रवेश कर repl (जो एक भागने <बैकस्लैश> में की आवश्यकता है पूर्व मोड और एक भागने <नियंत्रण> खुली या में वी vi मोड) उस बिंदु पर लाइन विभाजित करेगा, संपादन बफ़र में एक नई लाइन बनाने । <गाड़ी-वापसी> को छोड़ दिया जाएगा।

यूनिक्स हिस्ट्री आर्काइव में, बीएसडी एक्स / वी का पहला संस्करण 4.1cBSD में दिखाई देता है ( @(#)ex_re.c 7.2 10/16/81और 4BSD में मौजूद नहीं है @(#)ex_re.c 6.2 10/23/80) (4.1A और 4.1b आर्काइव में मौजूद नहीं हैं]।

प्रासंगिक कोड है:

/* ^V <return> from vi to split lines */
if (c == '\r')
    c = '\n';

यह समाचार फ़ाइल में भी उल्लिखित है :

Rs में ^ V <वापसी> का उपयोग करके vi से स्थानापन्न कमांड के साथ लाइनों को विभाजित करना अब संभव है। यह पूर्व कमांड मोड का उपयोग करने के लिए अंतिम अच्छे कारण का ख्याल रखता है।

पूर्व कमांड मोड में पूर्व समर्थित व्यवहार बैकस्लैश-एंटर (यानी एक वास्तविक न्यूलाइन के बाद बैकस्लैश) के लिए एक नई प्रविष्टि सम्मिलित करने के लिए था।


0

विषमता की उत्पत्ति कंप्यूटिंग इतिहास में एक तरीके से वापस जाती है।

लघु संस्करण:

<CR> & <LF>  (Carriage-Return and Linefeed) 
== 
\r & \n

लंबे संस्करण:
पहले स्क्रीन मूल रूप से टेलेटिप (टीटीवाई) के डिजिटल संस्करण थे और प्रिंटर के समान व्यवहार उत्पन्न करने के लिए नियंत्रण कोड का उपयोग करते थे। कैरिज-रिटर्न ने कर्सर (या प्रिंट-हेड) को शुरुआती कॉलम में ले लिया। अगली पंक्ति में (एक स्क्रीन पर) लाइनफीड उन्नत हुआ और एक पंक्ति आगे पेपर को खिलाया।

प्रिंटर के लिए, आपको एक युग्मित <CR><LF>करना होगा या आपका आउटपुट सही नहीं लगेगा। शुरुआती स्क्रीन पर, यह मुद्दा अभी भी सच था।

डॉस (और बाद में विंडोज) पुराने मानक का पालन करता है और पाठ को बचाता है <CRLF>

* NIX पाठ (जैसा कि अधिकांश vi उपयोगकर्ता परिचित हैं) केवल <LF>दक्षता के लिए उपयोग करता है।

विंडोज में परीक्षण करने के लिए, वर्ड / वर्डपैड का उपयोग करें और टेक्स्ट की कुछ पंक्तियों को "प्रकार: पाठ - एमएस-डॉस प्रारूप" के रूप में सहेजें। फिर वही फाइल नोटपैड में खोलें। यह सामान्य दिखना चाहिए। फिर उसी फ़ाइल को Word / Wordpad में "प्रकार: पाठ" पर सहेजें। नोटपैड सभी नई लाइनों को अनदेखा करेगा और लाइनों को एक साथ चलाएगा। [नोटपैड का पाठ प्रारूप \r\nसंयोजन के लिए डिफॉल्ट करता है जबकि वर्ड / वर्डपैड डिफ़ॉल्ट रूप से \n।]

\ r कोड समकक्ष है <CR>

\ n कोड के बराबर है <LF>

और vi के साथ मेरे (बहुत सीमित) अनुभव में, यह <CRLF>मेरे डॉस पाठ संपादक से संयोजन को "ठीक" करने की कोशिश करेगा । vi ने एक वर्ण को हटा दिया, जिसके साथ प्रतिस्थापित किया गया <NUL>। कारण का एक बड़ा हिस्सा मैंने vi का उपयोग करना बंद कर दिया।


2
जबकि अपने सभी जानकारी रोचक है, यह केवल बताता क्यों \rहै <CR>और \nहै <LF>। यह क्यों की वास्तविक प्रश्न को संबोधित नहीं करता \n\rव्यवहार करते हैं अलग ढंग से विभिन्न संदर्भों में।
तुम्बलर 41

धन्यवाद! :-) जब मैंने उत्तर दिया तो मैं इसे बदल रहा था। (अंतिम पैराग्राफ जोड़ा गया।)
रॉबिन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.