फ़ाइल के अंत में कोई नई पंक्ति नहीं


471

जब कर रहा है a git diff यह कहते हैं "फ़ाइल के अंत में कोई नई पंक्ति"

ठीक है, फ़ाइल के अंत में कोई नई रेखा नहीं है। क्या बड़ी बात है?

संदेश का क्या महत्व है और यह हमें क्या बताने की कोशिश कर रहा है?


11
शायद, अगर आपके पास एक ऐसी फ़ाइल है जो बिना किसी नई रेखा के समाप्त होती है, और आप एक और पंक्ति जोड़ते हैं, तो गिट को यह दिखाना होगा कि पूर्व की अंतिम पंक्ति बदल गई है, क्योंकि इसमें लाइन के भाग के रूप में न्यूलाइन वर्ण शामिल है?
nafg

जवाबों:


458

यह इंगित करता है कि आपके पास एक नई रेखा नहीं है (आमतौर पर) '\n' फ़ाइल के अंत में रेखा , उर्फ ​​सीआर या सीआरएलएफ) नहीं है।

यही है, सीधे शब्दों में कहें, तो फ़ाइल में अंतिम बाइट (या बाइट्स यदि आप विंडोज पर हैं) एक नई पंक्ति नहीं है।

संदेश प्रदर्शित किया जाता है क्योंकि अन्यथा एक फ़ाइल के बीच अंतर बताने का कोई तरीका नहीं है जहां अंत में एक नई रेखा है और जहां नहीं है। डिफाइन को किसी भी तरह से एक नई पंक्ति का उत्पादन करना पड़ता है, या परिणाम स्वचालित रूप से पढ़ने या प्रक्रिया करने के लिए कठिन होगा।

ध्यान दें कि एक नई शैली को हमेशा एक अंतिम चरित्र के रूप में रखना एक अच्छी शैली है यदि इसे फ़ाइल प्रारूप द्वारा अनुमति दी जाती है। इसके अलावा, उदाहरण के लिए, सी और सी ++ हेडर फ़ाइलों के लिए यह भाषा मानक द्वारा आवश्यक है।


135
जिज्ञासा से बाहर, क्या आप बता सकते हैं कि हमेशा एक नई शैली को अंतिम चरित्र के रूप में क्यों माना जाता है? संपादित करें: यह चर्चा मिली ।
पॉल बेलोरा

84
@PaulBellora ऐतिहासिक रूप से, यह C भाषा के मानक stackoverflow.com/a/729725/233098 द्वारा व्यावहारिक रूप से किया गया एक निर्णय था , क्योंकि कई Unix टूल को उचित प्रदर्शन stackoverflow.com/a/729795/233098 के लिए इसकी आवश्यकता या अपेक्षा है । दार्शनिक रूप से, क्योंकि एक पाठ फ़ाइल में प्रत्येक पंक्ति "एंड-ऑफ-लाइन" वर्ण के साथ समाप्त होती है - अंतिम पंक्ति को कोई अपवाद नहीं होना चाहिए। इसके बारे में अलग तरह से सोचते हुए, आइए इसका विलोम अन्वेषण करें। यदि "एंड-ऑफ-लाइन" के बजाय "स्टार्ट-ऑफ-लाइन" मार्कर था, तो क्या आप पहली लाइन पर "स्टार्ट-ऑफ-लाइन" कैरेक्टर को छोड़ देंगे?
जो

29
@ जो कि इतना समझ में नहीं आता है। एक नई लाइन एक नई लाइन है , यानी लाइनों के बीच विभाजक, एक अंत पंक्ति नहीं है। हमारे पास पंक्ति वर्णों की शुरुआत नहीं है क्योंकि वे आवश्यक नहीं हैं। हमारे पास समान कारणों के लिए पंक्ति वर्णों का अंत नहीं है।
अजय

6
@ संजय का तर्क है कि "विभाजक रेखाओं के बीच" बनाम "अंत-पंक्ति" के बीच स्वाभाविक रूप से बेहतर है। न तो दृश्य स्वाभाविक रूप से सही है या गलत, इसे देखने का सिर्फ एक तरीका है। मैं सुझाव दे रहा हूँ हम बिंदु का मानना है कि ऐतिहासिक दृष्टि से व्यावहारिक है, के बाद से हम पहले से ही इसे उस तरह से कर रहे हैं का उपयोग जारी है और यह करता है जब आप इसे स्वीकार कर भावना। संगति जरूरी है। "लाइनों के बीच विभाजक" के दृष्टिकोण के नाम पर इसे तोड़ने की कोई आवश्यकता नहीं है।
जो

17
@ नया "मेरे लिए नया" एक नया सम्मेलन नहीं है। यह किसी अन्य प्रकार के प्रोग्रामिंग सम्मेलन की खोज करने जैसा है। तुम बस इसके साथ जाओ। आप विचलन कर सकते हैं , लेकिन आप केवल खुद को अलग कर रहे हैं। (या इस मामले में, वास्तव में टूल को तोड़ना।) इस बारे में सोचें कि कितने अन्य लोगों ने कुछ रेल कन्वेंशन, या PEP8 की खोज की, और उन समुदायों के अनुरूप पूरी तरह से बने रहे क्योंकि उन्होंने इसके विपरीत लिखित कोड होने के बावजूद - दिया।
जो

100

यह सिर्फ खराब शैली नहीं है, यह फ़ाइल पर अन्य उपकरणों का उपयोग करते समय अप्रत्याशित व्यवहार को जन्म दे सकता है।

यहाँ है test.txt:

first line
second line

अंतिम पंक्ति पर कोई नया वर्ण नहीं है। आइए देखें कि फाइल में कितनी लाइनें हैं:

$ wc -l test.txt
1 test.txt

हो सकता है कि आप यही चाहते हों, लेकिन ज्यादातर मामलों में आप शायद उम्मीद करेंगे कि फाइल में 2 लाइनें हों।

इसके अलावा, यदि आप फ़ाइलों को संयोजित करना चाहते हैं तो यह उस तरीके का व्यवहार नहीं कर सकता है जिसकी आप अपेक्षा करेंगे:

$ cat test.txt test.txt
first line
second linefirst line
second line

अंत में, यदि आप एक नई पंक्ति जोड़ना चाहते हैं, तो यह आपके अंतर को थोड़ा अधिक शोर बना देगा। यदि आपने तीसरी पंक्ति जोड़ी है, तो यह दूसरी पंक्ति के साथ-साथ नए जोड़ को भी दिखाएगा।


4
बिल्ली का परिणाम ठीक है लेकिन wc पैरामीटर "-l, --lines" सिर्फ गलत है। यहां तक ​​कि यह मैनुअल कहता है "प्रिंट द न्यूलाइन काउंट्स" और न कि "लाइन काउंट्स प्रिंट करें"।
अविश्वसनीय जन

और मैं भी हाल ही में उपयोग लिनक्स (उपयोग- linux 2.34) के साथ इस (wc और बिल्ली) को पुन: पेश नहीं कर सकता।
wget

1
@ भूल जाओ मैं उपयोग-लाइन 2.34 पर हूं और यह पुष्टि कर सकता है कि यह उत्तर जो वर्णन करता है वह वर्तमान व्यवहार है। मेरा अनुमान है कि आपके संपादक ने "\ n" वर्ण जोड़ा है।
Stephanos

29

एकमात्र कारण यह है कि यूनिक्स ऐतिहासिक रूप से सभी मानव-पठनीय पाठ फ़ाइलों का एक सम्मेलन एक नई पंक्ति में समाप्त हो रहा था। उस समय, यह टेक्स्ट फ़ाइलों को प्रदर्शित करने या शामिल करने के दौरान अतिरिक्त प्रसंस्करण से बचता था, और अन्य प्रकार के डेटा (उदाहरण के लिए कच्चे बाइनरी डेटा जो मानव-पठनीय नहीं है) वाली फ़ाइलों के लिए अलग-अलग तरीके से पाठ फ़ाइलों से बचने से बचता है।

इस सम्मेलन के कारण, उस युग के कई उपकरण टेक्स्ट एडिटर, डिफरेंट टूल और अन्य टेक्स्ट प्रोसेसिंग टूल सहित नईलाइन की समाप्ति की उम्मीद करते हैं। मैक ओएस एक्स को बीएसडी यूनिक्स पर बनाया गया था, और लिनक्स को यूनिक्स-संगत होने के लिए विकसित किया गया था, इसलिए दोनों ऑपरेटिंग सिस्टम को एक ही सम्मेलन, व्यवहार और उपकरण विरासत में मिले हैं।

विंडोज को यूनिक्स-संगत होने के लिए विकसित नहीं किया गया था, इसलिए इसमें एक ही सम्मेलन नहीं है, और अधिकांश विंडोज सॉफ्टवेयर बिना किसी अनुवर्ती रूपरेखा के ठीक से निपटेंगे।

लेकिन, चूंकि Git को पहले Linux के लिए विकसित किया गया था, और बहुत सारे ओपन-सोर्स सॉफ्टवेयर यूनिक्स-संगत सिस्टम जैसे लिनक्स, मैक ओएस एक्स, फ्रीबीएसडी आदि पर बनाए गए हैं, अधिकांश ओपन-सोर्स समुदाय और उनके उपकरण (प्रोग्रामिंग भाषा सहित) जारी हैं इन सम्मेलनों का पालन करने के लिए।

ऐसे तकनीकी कारण हैं जो 1971 में समझ में आए, लेकिन इस युग में यह ज्यादातर सम्मेलन है और मौजूदा उपकरणों के साथ संगतता बनाए रखता है।


23

यदि आप मौजूदा फ़ाइल के अंत में एक नई पंक्ति जोड़ते हैं जिसमें पहले से ही ए नहीं हैnewline character से ही अंत नहीं है, तो अंतर पुरानी अंतिम पंक्ति को संशोधित करते हुए दिखाएगा, भले ही वैचारिक रूप से यह नहीं था।

यह एक जोड़ने के लिए कम से कम एक अच्छा कारण है newline character अंत में ।

उदाहरण

एक फ़ाइल में शामिल है:

A() {
    // do something
}

Hexdump:

00000000: 4128 2920 7b0a 2020 2020 2f2f 2064 6f20  A() {.    // do 
00000010: 736f 6d65 7468 696e 670a 7d              something.}

अब आप इसे संपादित करते हैं

A() {
    // do something
}
// Useful comment

Hexdump:

00000000: 4128 2920 7b0a 2020 2020 2f2f 2064 6f20  A() {.    // do 
00000010: 736f 6d65 7468 696e 670a 7d0a 2f2f 2055  something.}.// U
00000020: 7365 6675 6c20 636f 6d6d 656e 742e 0a    seful comment..

गिट डिफरेंस दिखाएगा:

-}
\ No newline at end of file
+}
+// Useful comment.

दूसरे शब्दों में, यह वैचारिक रूप से घटित एक बड़े अंतर को दर्शाता है। यह दिखाता है कि आपने लाइन हटा दी है और लाइन }जोड़ दी है }\n। यह वास्तव में है, जो हुआ, लेकिन यह वैचारिक रूप से नहीं हुआ, इसलिए यह भ्रमित हो सकता है।


2
हम दूसरी दिशा में एक ही बात लिख सकते हैं: यदि आप मौजूदा फ़ाइल के अंत में एक नई लाइन हटाते हैं, जो पहले से ही एक नई लाइन है, तो अंतर पुरानी अंतिम पंक्ति को भी संशोधित रूप में दिखाएगा, जब वैचारिक रूप से इसके नहीं। कम से कम एक अच्छा कारण अंत में एक नई लाइन को हटाने के लिए।
gentiane

3
@gentiane आप "एक नई पंक्ति" (एक नई पंक्ति) और "एक नई पंक्ति" (1 या 2 वर्ण एक पंक्ति के अंत में परिसीमन कर रहे हैं) को भ्रमित कर रहे हैं
Myxew

@minexew नहीं, gentiane नहीं है। हो सकता है कि आपको यह एहसास न हो कि "एक नई पंक्ति" "एक नई पंक्ति" के समान है।
अविश्वसनीय जन

3
@ TheincredibleJan जिस तरह से वे उत्तर में उपयोग किए जाते हैं, दो शब्दों के अलग-अलग अर्थ होते हैं। मुझे नहीं पता कि आप स्मार्ट-गधा बनने की कोशिश कर रहे हैं या सिर्फ गलतफहमी है कि क्या हो रहा है।
21

18

यह केवल इंगित करता है कि फ़ाइल के अंत में एक नई रेखा नहीं है। यह एक तबाही नहीं है, यह सिर्फ यह स्पष्ट करने के लिए एक संदेश है कि कमांड लाइन में एक अंतर को देखते समय ऐसा कोई नहीं है।


10

इस सम्मेलन के व्यवहार में आने का कारण यह है कि यूनिक्स जैसे ऑपरेटिंग सिस्टम पर एक नई लाइन वर्ण को एक लाइन टर्मिनेटर और / या संदेश सीमा के रूप में माना जाता है (इसमें प्रक्रियाओं, लाइन बफरिंग, आदि के बीच पाइपिंग शामिल है)।

उदाहरण के लिए, विचार करें कि केवल एक नई लाइन वर्ण वाली फ़ाइल को एकल, रिक्त पंक्ति के रूप में माना जाता है। इसके विपरीत, शून्य बाइट की लंबाई वाली एक फाइल वास्तव में शून्य लाइनों वाली एक खाली फाइल है। यह wc -lआदेश के अनुसार पुष्टि की जा सकती है ।

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


1
मुझे नीचे क्यों रखा गया है -2? मैंने न केवल इस बात की पुष्टि की कि अन्य उत्तर क्या कहे गए हैं (यानी मानक UNIX- आधारित उपकरण लाइनों के लिए एक टर्मिनेटर के रूप में एक नई रेखा की अपेक्षा करते हैं), लेकिन यह भी कि एक खाली फ़ाइल से एक खाली फ़ाइल को अलग करने का कोई तरीका नहीं है, जो बिल्कुल सच है । मैंने विशेष रूप से मूल प्रश्न का उत्तर दिया "संदेश का क्या महत्व है और यह हमें क्या बताने की कोशिश कर रहा है?"
लेस्ली क्राऊस

मैंने आपको अस्वीकार नहीं किया, लेकिन यह प्रतिक्रिया यूनिक्स प्रकार प्रणालियों के लिए विशिष्ट प्रतीत होती है, यह केवल तब लागू होता है जब एक नई लाइन सिर्फ नई पंक्ति वर्ण होती है। यह स्पष्ट नहीं है कि यहां लागू होता है। इसके अलावा, चेतावनी बेकार लगती है अगर फ़ाइल में सिर्फ एक खाली लाइन होती है। हालाँकि, मैं स्टैकओवरफ़्लो से बचता हूँ क्योंकि लोग अक्सर बिना किसी स्पष्टीकरण के निराश हो जाते हैं।
user34660

9

वहाँ एक बात है कि मैं पिछले प्रतिक्रियाओं में नहीं दिख रहा है। जब कोई फ़ाइल के एक हिस्से को काट दिया गया हो, तो बिना किसी लाइन के चेतावनी चेतावनी हो सकती है। यह लापता डेटा का एक लक्षण हो सकता है।


सामान्य तौर पर अच्छी बात है, लेकिन मुझे नहीं लगता कि यह इस विशेष प्रश्न के संदर्भ में समझ में आता है।
cst1992

@ Ststoverflow में cst1992 उत्तर को यथासंभव उपयोगी माना जाता है, जिसका अर्थ है कि वे सभी संभावनाओं पर लागू होते हैं। सवाल छोटा है और मैं नहीं देखता कि यह मेरे द्वारा सुझाई गई संभावना को छोड़कर कहाँ है।
user34660

7

मुख्य समस्या वह है जो आप लाइन को परिभाषित करते हैं और क्या अंत-ऑन-लाइन वर्ण अनुक्रम लाइन का हिस्सा है या नहीं। UNIX- आधारित संपादक (जैसे VIM) या टूल (जैसे Git) EOL वर्ण क्रम का उपयोग लाइन टर्मिनेटर के रूप में करते हैं, इसलिए यह लाइन का एक हिस्सा है। यह सी और पास्कल में अर्धविराम (?) के उपयोग के समान है। सी अर्धविराम में बयानों को समाप्त करता है, पास्कल में यह उन्हें अलग करता है।


4

यह वास्तव में एक समस्या का कारण बनता है क्योंकि लाइन एंडिंग स्वचालित रूप से संशोधित की गई फ़ाइलों को बिना किसी बदलाव के संशोधित करती है। संकल्प के लिए इस पोस्ट को देखें।

CRLF के साथ LF की जगह git


3

स्रोत फ़ाइलों को अक्सर उपकरण (सी, सी ++: हेडर फाइलें, जावास्क्रिप्ट: बंडलर्स) द्वारा संक्षिप्त किया जाता है। यदि आप नई लाइन वर्ण को छोड़ देते हैं, तो आप गंदे कीड़े (जहां एक स्रोत की अंतिम पंक्ति को अगली स्रोत फ़ाइल की पहली पंक्ति के साथ संक्षिप्त किया जाता है) को पेश कर सकते हैं। उम्मीद है कि सभी सोर्स कोड कॉनैट टूल्स वैसे भी कॉन्टेक्टेड फाइल्स के बीच एक नई लाइन डालते हैं लेकिन ऐसा हमेशा नहीं होता है।

इस मुद्दे की जड़ यह है कि - अधिकांश भाषाओं में, न्यूलाइन्स का अर्थ अर्थ होता है और एंड-ऑफ-फाइल न्यूलाइन वर्ण के लिए परिभाषित भाषा नहीं है। इसलिए आपको हर कथन / अभिव्यक्ति को एक नए चरित्र के साथ समाप्त करना चाहिए - जिसमें अंतिम भी शामिल है।


1
C / C ++ में आप अपनी पूरी परियोजना को एक पंक्ति में लिख सकते हैं। न्यूलाइन की जरूरत नहीं।
अविश्वसनीय जन

आप हो सकता है एक पंक्ति में अपने पूरे परियोजना लिखना ... अगर आप एक का उपयोग नहीं करते //कोड के बीच में शैली टिप्पणी।
डग कोबर्न

2

आपकी मूल फ़ाइल में संभवतः कोई नया वर्ण नहीं था।

हालांकि, कुछ संपादकों को गेडिट पसंद है linux में चुपचाप फ़ाइल के अंत में newline जोड़ता है। इस प्रकार के संपादकों का उपयोग करते हुए आप इस संदेश से छुटकारा नहीं पा सकते हैं।

इस मुद्दे को दूर करने के लिए मैंने दृश्य स्टूडियो कोड संपादक के साथ फाइल खोलने की कोशिश की

यह संपादक स्पष्ट रूप से अंतिम पंक्ति दिखाता है और आप अपनी इच्छानुसार पंक्ति को हटा सकते हैं।


0

जब यह लायक है, तब मैंने इसका सामना किया जब मैंने मैक पर एक इंटेलीज प्रोजेक्ट बनाया, और फिर प्रोजेक्ट को मेरी विंडोज मशीन पर स्थानांतरित कर दिया। मुझे मैन्युअल रूप से हर फाइल को खोलना था और IntelliJ विंडो के नीचे दाईं ओर एन्कोडिंग सेटिंग बदलनी थी। शायद सबसे ज्यादा नहीं हो रहा है अगर कोई भी जो इस सवाल को पढ़ता है, लेकिन मुझे कुछ घंटों के काम से बचाया जा सकता है ...

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