फ़ाइल के अंत में एक नई लाइन जोड़ने का क्या मतलब है?


165

कुछ संकलक (विशेषकर C या C ++ वाले) आपको इसके बारे में चेतावनी देते हैं:

No new line at end of file

मैंने सोचा कि यह एक सी-प्रोग्रामर-केवल समस्या होगी, लेकिन जीथब एक संदेश को प्रतिबद्ध दृश्य में प्रदर्शित करता है:

\ No newline at end of file

एक PHP फ़ाइल के लिए।

मैं समझता हूं कि इस धागे में बताई गई प्रीप्रोसेसर चीज , लेकिन PHP के साथ इसका क्या संबंध है? क्या यह एक ही include()बात है या यह \r\nबनाम \nविषय से संबंधित है ?

किसी फ़ाइल के अंत में एक नई लाइन होने का क्या मतलब है?


SO से डुप्लिकेट: stackoverflow.com/questions/729692/…
AlikElzin-kilaka

2
लोगों को दूर करने के लिए।
एंड्रयू

3
यदि आप catफ़ाइल करते हैं, तो अगला प्रॉम्प्ट अंतिम "लाइन" में जोड़ा जाएगा यदि यह एक नई पंक्ति के साथ समाप्त नहीं होता है।
एरॉन फ्रेंक

जवाबों:


185

यह एक फ़ाइल के अंत में एक अतिरिक्त न्यूलाइन जोड़ने के बारे में नहीं है, यह उस नईलाइन को हटाने के बारे में नहीं है जो वहां होनी चाहिए।

एक पाठ फ़ाइल , यूनिक्स के तहत, लाइनों की एक श्रृंखला होती है , जिनमें से प्रत्येक एक नई पंक्ति वर्ण ( \n) के साथ समाप्त होती है । एक फ़ाइल जो खाली नहीं है और एक नई पंक्ति के साथ समाप्त नहीं होती है इसलिए पाठ फ़ाइल नहीं है।

पाठ फ़ाइलों पर संचालित होने वाली उपयोगिताएँ उन फ़ाइलों के साथ अच्छी तरह से सामना नहीं कर सकती हैं जो एक नई पंक्ति के साथ समाप्त नहीं होती हैं; ऐतिहासिक यूनिक्स उपयोगिताओं उदाहरण के लिए, अंतिम नई पंक्ति के बाद पाठ को अनदेखा कर सकती है। GNU उपयोगिताओं में गैर-पाठ फ़ाइलों के साथ शालीनता से व्यवहार करने की नीति है, और इसलिए अधिकांश अन्य आधुनिक उपयोगिताओं हैं, लेकिन आप अभी भी उन फाइलों के साथ अजीब व्यवहार का सामना कर सकते हैं जो एक अंतिम newline¹ याद कर रहे हैं।

जीएनयू के साथ, अगर एक फाइल की तुलना एक न्यूलाइन के साथ हो रही है, लेकिन दूसरी नहीं है, तो उस तथ्य को नोट करना सावधानी है। चूंकि अंतर लाइन-ओरिएंटेड है, यह फाइलों में से किसी एक के लिए एक नई लाइन को स्टोर करके इसे इंगित नहीं कर सकता है, लेकिन दूसरों के लिए नहीं - नईलाइन यह इंगित करने के लिए आवश्यक है कि कहां से अलग फाइल शुरू और समाप्त होती है। तो \ No newline at end of fileएक फ़ाइल में अंतर करने के लिए इस विशेष पाठ का उपयोग करें जो एक फ़ाइल से एक नई पंक्ति में समाप्त नहीं हुआ था।

वैसे, सी संदर्भ में, स्रोत फ़ाइल में समान रूप से लाइनों की एक श्रृंखला होती है। अधिक सटीक रूप से, एक अनुवाद इकाई को कार्यान्वयन-परिभाषित लाइनों की एक श्रृंखला के रूप में देखा जाता है, जिनमें से प्रत्येक को एक नई पंक्ति वर्ण ( n1256 n5.1.1.1) के साथ समाप्त होना चाहिए । यूनिक्स प्रणालियों पर, मानचित्रण सीधा है। डॉस और विंडोज पर, प्रत्येक सीआर एलएफ अनुक्रम ( \r\n) को एक नई पंक्ति में मैप किया जाता है ( \n, यह हमेशा ऐसा होता है जब इन ओएस पर पाठ के रूप में खोली गई फ़ाइल को पढ़ते हुए)। कुछ OS ऐसे हैं, जिनमें एक नई पंक्ति नहीं है, लेकिन इसके बजाय निश्चित हैं- या चर-आकार के रिकॉर्ड; इन प्रणालियों पर, फ़ाइलों से सी स्रोत पर मैपिंग एक परिचय\nप्रत्येक रिकॉर्ड के अंत में। हालांकि यह यूनिक्स के लिए सीधे प्रासंगिक नहीं है, इसका मतलब यह है कि यदि आप एक सी स्रोत फ़ाइल की प्रतिलिपि बनाते हैं जो रिकॉर्ड-आधारित पाठ फ़ाइलों के साथ सिस्टम में इसकी अंतिम नई लाइन को याद कर रही है, तो इसे वापस कॉपी करें, आप या तो अपूर्ण के साथ समाप्त हो जाएंगे पिछली पंक्ति को प्रारंभिक रूपांतरण में काट दिया गया था, या रिवर्स रूपांतरण के दौरान इस पर एक अतिरिक्त नई रेखा से निबटा गया था।

¹ उदाहरण: GNU सॉर्ट का आउटपुट हमेशा एक नई रेखा के साथ समाप्त होता है। इसलिए यदि फ़ाइल fooअपनी अंतिम नई लाइन को याद कर रही है, तो आप पाएंगे कि sort foo | wc -cएक से अधिक वर्णों की रिपोर्ट करता है cat foo | wc -c


के बारे में "... लाइनों की श्रृंखला, जिनमें से प्रत्येक को एक नया चरित्र (n1256 §5.1.1.1) के साथ समाप्त होना चाहिए" -> एक और हाल ही में C11dr N1570 को फिर से देखने पर, शायद इसके लिए अन्य के लिए समर्थन नहीं मिला: "एक स्रोत फ़ाइल जो खाली नहीं है, एक नई-पंक्ति वर्ण में समाप्त हो जाएगी, जो कि किसी भी तरह के स्पाइसिंग के होने से पहले एक बैकस्लैश चरित्र द्वारा तुरंत पूर्ववर्ती नहीं होगी।" §5.1.1.2 2, लेकिन ऐसा लगता है कि स्पाइसिंग विनिर्देशों के लिए प्रतिबंधित है।
chux

@chux यह वाक्य n1256 में भी मौजूद है। अंतिम पंक्ति एक नई पंक्ति के साथ समाप्त होनी चाहिए। वे रेखाएँ जो अंतिम रेखा नहीं हैं, उन्हें स्पष्ट रूप से यह बताने के लिए कि यह पंक्ति समाप्त होती है और अगली पंक्ति शुरू होती है, एक नई वर्ण रेखा के साथ समाप्त होनी चाहिए। इस प्रकार हर पंक्ति को एक नए वर्ण के साथ समाप्त होना चाहिए।
गाइल्स

हम्म्म, मेरे लिए, वह लाइन "" एक स्रोत फ़ाइल ... स्पाइसीलिंग होती है। "कैसे स्पाइकलिंग विचारों तक सीमित हो सकती है और सामान्य रूप से फाइलें नहीं। फिर भी मैं देखती हूं कि कोई व्यक्ति अन्यथा कैसे देख सकता है। शायद मैं एक पोस्ट की तलाश करूंगा। उस पर ध्यान केंद्रित करता है।
chux

> "तो फ़ाइल को अलग करने के लिए फ़ाइल के अंत में इस विशेष टेक्स्ट \ No newline का उपयोग करें जो कि एक फ़ाइल से एक नई पंक्ति में समाप्त नहीं हुआ था।" गिट इस पाठ को न केवल तब दिखाता है जब यह फाइलों की तुलना करता है। लेकिन तब भी जब नई फाइल को git में जोड़ा गया। इसलिए यह तर्क मान्य नहीं है, मुझे लगता है।
विक्टर क्रुगलिकोव

> "उपयोगिताएँ जो पाठ फ़ाइलों पर काम करने वाली हैं वे उन फ़ाइलों के साथ अच्छी तरह से सामना नहीं कर सकती हैं जो एक नई पंक्ति के साथ समाप्त नहीं होती हैं" मुझे नहीं लगता कि यह POSIX के कारण लापता \ n जैसी निम्न स्तर की समस्याओं के बारे में देखभाल करने के लिए git का व्यवसाय है। आवश्यकताओं। मुझे लगता है कि अगर git यह संदेश दिखाता है, तो इसका कारण स्रोत नियंत्रण समस्याओं में होना चाहिए ।
विक्टर क्रुग्लिकोव

41

जरूरी नहीं कि इसका कारण हो, लेकिन नई लाइन के साथ समाप्त न होने वाली फाइलों का व्यावहारिक परिणाम:

विचार करें कि यदि आप कई फ़ाइलों का उपयोग करना चाहते हैं तो क्या होगा cat। उदाहरण के लिए, यदि आप fooलाइन को 3 फाइलों के आर-पार शुरू करना चाहते हैं :

cat file1 file2 file3 | grep -e '^foo'

अगर फाइल 3 में पहली लाइन शुरू होती है foo, लेकिन फाइल 2 की \nअंतिम लाइन के बाद फाइनल नहीं होता है, तो यह घटना grep द्वारा नहीं मिलेगी, क्योंकि फाइल 2 में आखिरी लाइन और फाइल 3 में पहली लाइन grep द्वारा सिंगल के रूप में देखी जाएगी। लाइन।

इसलिए, निरंतरता के लिए और आश्चर्य से बचने के लिए मैं अपनी फ़ाइलों को हमेशा एक नई पंक्ति के साथ समाप्त करने की कोशिश करता हूं।


लेकिन क्या यह फाइलों के रख-रखाव के बारे में ध्यान रखने का व्यवसाय है?
विक्टर क्रुग्लिकोव

क्या इसका कारण यह नहीं है कि आपको '\n'बिल्ली के ऑपरेशन में बस लगाना चाहिए ...
एंड्रयू

3
यह कहने की तरह है, "कभी-कभी मैं स्ट्रिंग्स को एक साथ जोड़ देता हूं \n, जिसमें छोर या व्हाट्सएप होता है, इसलिए चीजों को लगातार बनाए रखने के लिए, मैं हमेशा \n _____अपने स्ट्रिंग्स के दोनों छोर पर रखता हूं।" ठीक है, नहीं, अपनी स्ट्रिंग्स को ट्रिम करवाने और फिर उन्हें सही तरीके से करने के लिए सही काम करना है।
एंड्रयू

16

इसके दो पहलू हैं:

  1. कुछ सी कंपाइलर हैं जो अंतिम पंक्ति को पार्स नहीं कर सकते हैं यदि यह एक नई रेखा के साथ समाप्त नहीं होता है। सी मानक निर्दिष्ट करता है कि एक सी फाइल को एक नई लाइन (सी 11, 5.1.1.2, 2.) के साथ समाप्त होना चाहिए और एक नई लाइन के बिना एक अंतिम पंक्ति अपरिभाषित व्यवहार (सी 11, जे। 2, 2 आइटम) पैदा करती है। शायद ऐतिहासिक कारणों से, क्योंकि इस तरह के संकलक के कुछ विक्रेता पहले मानक लिखे जाने पर समिति का हिस्सा थे। इस प्रकार जीसीसी द्वारा चेतावनी।

  2. diffप्रोग्राम (जैसे द्वारा उपयोग किया जाता है git diff, जीथब आदि) फाइलों के बीच लाइन अंतर द्वारा लाइन दिखाते हैं। वे आम तौर पर एक संदेश प्रिंट करते हैं जब केवल एक फ़ाइल एक नई पंक्ति के साथ समाप्त होती है क्योंकि अन्य आपको यह अंतर नहीं दिखाई देगा। उदाहरण के लिए अगर दो फ़ाइलों के बीच फर्क सिर्फ इतना है, पिछले न्यू लाइन चरित्र की उपस्थिति है संकेत यह दोनों फ़ाइलों को कैसा लगेगा के बिना एक ही थे, जब diffऔर cmpएक निकास-कोड असमान सफलता और फ़ाइलों के चेकसम वापसी (जैसे के माध्यम से md5sum) मेल नहीं खाते।



अंतर की तरह लगता है बस चालाक होना चाहिए।
एंड्रयू

@ और, नहीं, यह नहीं है। diffयदि कोई हो और अगर एक फ़ाइल में अंतिम वर्ण के रूप में एक नई पंक्ति है जबकि दूसरी नहीं है, तो उस अंतर को आउटपुट में किसी तरह ध्यान देने योग्य होना चाहिए।
मैक्सक्लेपजिग

आपका बाद वाला कथन सही है। हालाँकि, अंतर दर्शक को "newlines" ( \n) को शुरू करने के लिए प्रदर्शित करने की आवश्यकता नहीं है , इसके बजाय यह केवल "नई लाइनें" दिखा सकता है।
एंड्रयू

10

\ No newline at end of fileआप से मिल GitHub एक पैच के अंत में दिखाई (में diffप्रारूप , "एकीकृत प्रारूप" अनुभाग के अंत में टिप्पणी देखें)।

कंपाइलर को इस बात की परवाह नहीं है कि किसी फाइल के अंत में कोई नईलाइन है या नहीं, लेकिन git(और diff/ patchयूटिलिटीज) को उन खातों को लेना होगा। उसके कई कारण हैं। उदाहरण के लिए, किसी फ़ाइल के अंत में एक नई पंक्ति जोड़ने या हटाने के लिए भूल जाने से उसका हैशसम ( md5sum/ sha1sum) बदल जाएगा । इसके अलावा, फाइलें हमेशा प्रोग्राम नहीं होती हैं, और एक अंतिम \nकुछ अंतर हो सकता है।

नोट : सी संकलक से चेतावनी के बारे में, मुझे लगता है कि वे पिछड़े संगतता उद्देश्यों के लिए एक अंतिम नई लाइन के लिए जोर देते हैं। बहुत पुरानी कंपाइलर अंतिम पंक्ति को स्वीकार नहीं कर सकते हैं यदि \n(या अन्य सिस्टम-डिपेंडेंट एंड-ऑफ-लाइन चार अनुक्रम) के साथ समाप्त नहीं होती है।


7
"मुझे लगता है कि वे पिछड़े संगतता प्रयोजनों के लिए एक अंतिम नई लाइन के लिए जोर देते हैं" - नहीं, वे इस पर जोर देते हैं क्योंकि सी मानक इसे लागू करता है।
MestreLion

1
@MestreLion C को C स्रोत कोड (C11 .15.1.1.2 2) के लिए अंतिम नई पंक्ति की आवश्यकता है। ध्यान दें कि पाठ फ़ाइल I / O के लिए, C में "अंतिम पंक्ति के लिए एक नई लाइन वर्ण की आवश्यकता है, जिसे कार्यान्वयन-परिभाषित किया गया है।" §7.21.2 2
chux

कौन बहुत पुराने संकलक का उपयोग कर रहा है? उनका उपयोग बंद करो।
एंड्रयू

1
@MestreLion: और आपको क्यों लगता है कि C मानक इसे अनिवार्य करता है ...
Stéphane Gimenez

@ StéphaneGimenez: विभिन्न OSes (POSIX भी '\ n' में समाप्त होने वाली रेखाओं को परिभाषित करता है) के बीच स्थिरता, बेहतर संगतता और अंतर-क्षमता
MestreLion

4

POSIX, यह ऑपरेटिंग सिस्टम के बीच संगतता बनाए रखने के लिए IEEE द्वारा निर्दिष्ट मानकों का एक समूह है।

जिनमें से एक "लाइन" की परिभाषा है, जो शून्य या अधिक गैर-वर्णों के अनुक्रम के साथ-साथ एक समाप्ति न्यूलाइन वर्ण है।

तो उस अंतिम पंक्ति को वास्तविक "लाइन" के रूप में पहचाना जाना चाहिए, जिसमें एक नई लाइन वर्ण की समाप्ति होनी चाहिए।

यह महत्वपूर्ण है यदि आप अपनी फ़ाइल को पार्स करने या विभाजन / सहायता करने के लिए OS टूल पर निर्भर हैं। यह देखते हुए कि PHP एक स्क्रिप्ट भाषा है, विशेष रूप से अपने शुरुआती दिनों में या यहां तक ​​कि अब भी (मुझे कोई विचार / पोस्टिंग नहीं है) यह पूरी तरह से ओएस निर्भरता थी।

हकीकत में, अधिकांश ऑपरेटिंग सिस्टम पूरी तरह से POSIX अनुरूप नहीं हैं और मनुष्य उस मशीन की तरह नहीं हैं या यहां तक ​​कि नई लाइनों को समाप्त करने की भी परवाह नहीं करते हैं। तो ज्यादातर चीजों के लिए इसकी हर चीज का एक स्मोर्गास्बॉर्ड या तो इसके बारे में परवाह करता है, चेतावनी देता है या बस इतना ही जाता है कि आखिरी सा पाठ वास्तव में एक लाइन है इसलिए इसे शामिल करें।


3

अलग इतिहास रखने की बात भी है। यदि कोई फ़ाइल बिना किसी नए वर्ण के समाप्त होती है, तो फ़ाइल के अंत में कुछ भी जोड़कर अंतिम उपयोगिता को उस अंतिम पंक्ति को बदलते हुए देखा जाएगा (क्योंकि \nइसमें जोड़ा जा रहा है)।

इसके कारण git blameऔर जैसे आदेशों के साथ अवांछित परिणाम हो सकते हैं hg annotate


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