Dosyanın sonunda yeni satır yok


473

Bunu yaparken "Dosya sonunda satırsonu yok"git diff yazıyor .

Tamam, dosyanın sonunda yeni satır yok. Sorun ne?

Mesajın önemi nedir ve bize ne anlatmaya çalışıyor?


11
Yeni satır olmadan biten bir dosyanız varsa ve başka bir satır eklerseniz, git satırın bir parçası olarak satırsonu karakterini içerdiğinden git'in önceki son satırın değiştiğini göstermesi gerekir?
nafg

Yanıtlar:


459

'\n'Dosyanın sonunda yeni bir satıra (genellikle CR veya CRLF) sahip olmadığınızı gösterir .

Yani, basitçe, dosyadaki son bayt (veya Windows'daysanız bayt) bir satırsonu değildir.

İleti görüntülenir, çünkü aksi takdirde, sonunda bir satırsonu olan ve olmayan bir dosya arasındaki farkı anlamanın bir yolu yoktur. Diff yine de bir satırsonu çıkarmalıdır, aksi takdirde sonuç otomatik olarak okunması veya işlenmesi zorlaşır.

Dosya formatı tarafından izin veriliyorsa, yeni satırı her zaman son karakter olarak koymanın iyi bir stil olduğunu unutmayın. Ayrıca, örneğin, C ve C ++ başlık dosyaları için dil standardı gereklidir.


137
Meraktan, son karakter olarak her zaman yeni bir satır koymanın neden iyi bir stil olarak kabul edildiğini açıklayabilir misiniz? Düzenle: bu tartışmayı buldu .
Paul Bellora

84
@PaulBellora Tarihsel olarak, C dili standardı stackoverflow.com/a/729725/233098 tarafından verilen bir karardı Pratik olarak, çünkü birçok Unix aracı düzgün bir ekran stackoverflow.com/a/729795/233098 gerektirir . Felsefi olarak, bir metin dosyasındaki her satır bir "satır sonu" karakteriyle sona erdiğinden - son satır herhangi bir istisna olmamalıdır. Bunu farklı düşünerek, tersini keşfedelim. "Satır sonu" yerine "satır başı" işareti olsaydı, ilk satırdaki "satır başı" karakterini atlar mıydınız?
Joe

29
@Joe Bu pek mantıklı değil. Bir satır a, yeni bir satır , çizgi arasındaki ayırıcı değil, bir sonu hattı yani. Satır karakterlerinin başlangıcı yok çünkü gerekli değiller. Aynı nedenden dolayı satır sonu karakterimiz yok.
acjay

6
@acjay "Satırlar arası ayırıcı" ile "satır sonu" arasında doğal olarak daha iyi olduğunu iddia ediyorum. Her iki görünüm de doğal olarak doğru ya da yanlış değildir, ona bakmanın tek bir yolu vardır. Bence point-of-view biz zaten o şekilde yapıyoruz, çünkü tarihsel olarak pratik kullanmaya devam ve öneriyorum yapar bunu kabul zaman mantıklı. Tutarlılık önemlidir. Bunu "satırlar arasındaki ayırıcı" bakış açısından kırmaya gerek yoktur.
Joe

17
@WORMSS "Benim için yeni", "yeni bir sözleşme" ile aynı şey değildir. Bu, başka herhangi bir programlama kuralını keşfetmek gibidir. Sadece onunla git. Sen olabilir sapma, ama sadece kendini tecrit ediyoruz. (Ya da bu durumda, aslında araçları kırmak.) Başkalarının kaç tane Rails konvansiyonu veya PEP8 keşfettiğini ve bu toplulukların bir bütün olarak ne kadar tutarlı kaldıklarını düşünün - aksi halde yazılı kod olmasına rağmen.
Joe

100

Sadece kötü bir stil değil, dosyadaki diğer araçları kullanırken beklenmedik davranışlara yol açabilir.

İşte test.txt:

first line
second line

Son satırda yeni satır karakteri yok. Dosyada kaç satır olduğunu görelim:

$ wc -l test.txt
1 test.txt

Belki de bunu istersiniz, ancak çoğu durumda dosyada 2 satır olmasını beklersiniz.

Ayrıca, dosyaları birleştirmek istiyorsanız, beklediğiniz gibi davranmayabilir:

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

Son olarak, yeni bir satır ekleyecekseniz farklarınızı biraz daha gürültülü yapar. Üçüncü bir satır eklediyseniz, yeni satırın yanı sıra ikinci satıra da bir düzenleme gösterir.


4
Cat sonucu iyi ancak "-l, --lines" wc parametresi yanlış. El ile bile "satır sayısını yazdır" değil, "yeni satır sayısını yazdır" yazıyor.
İnanılmaz Ocak

Ve bunu (wc ve cat) son util linux (util-linux 2.34) ile bile üretemiyorum.
wget

1
@wget util-linux 2.34 kullanıyorum ve bu cevabın açıkladığı şeyin mevcut davranış olduğunu doğrulayabilir. Tahminimce editörünüz "\ n" karakterini ekledi.
stephanos

29

Bunun tek nedeni, Unix'in tarihsel olarak, yeni satırla biten, insan tarafından okunabilen tüm metin dosyalarının bir sözleşmesine sahip olmasıdır. O zaman, bu, metin dosyalarını görüntülerken veya birleştirirken fazladan işlemden kaçındı ve metin dosyalarına diğer veri türlerini içeren dosyalardan farklı şekilde işlemden kaçınıldı (örneğin, insan tarafından okunamayan ham ikili veriler).

Bu kural nedeniyle, o döneme ait birçok araç, metin editörleri, farklı araçlar ve diğer metin işleme araçları da dahil olmak üzere bitiş satırını bekler. Mac OS X, BSD Unix üzerine inşa edildi ve Linux, Unix uyumlu olacak şekilde geliştirildi, bu nedenle her iki işletim sistemi de aynı kural, davranış ve araçları miras aldı.

Windows Unix uyumlu olacak şekilde geliştirilmemiştir, bu nedenle aynı kurala sahip değildir ve çoğu Windows yazılımı, takip eden yeni satır olmadan iyi bir şekilde ilgilenecektir.

Ancak Git önce Linux için geliştirildiğinden ve Linux, Mac OS X, FreeBSD vb.Gibi Unix uyumlu sistemlerde birçok açık kaynaklı yazılım oluşturulduğundan, çoğu açık kaynak topluluğu ve araçları (programlama dilleri dahil) devam ediyor bu sözleşmeleri takip etmek.

1971'de mantıklı olan teknik nedenler var, ancak bu dönemde çoğunlukla konvansiyon ve mevcut araçlarla uyumluluğu korumak.


23

Varolan dosyanın sonuna zaten sonunda olmayan yeni bir metin satırı eklerseniz newline character, fark kavramsal olarak olmasa bile eski son satırı değiştirilmiş olarak gösterir.

Bu, newline charactersonuna a eklemek için en az bir iyi nedendir .

Misal

Bir dosya şunları içerir:

A() {
    // do something
}

HexDump:

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

Şimdi düzenleyin

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..

Git diff şunu gösterir:

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

Başka bir deyişle, kavramsal olarak gerçekleşenden daha büyük bir fark gösterir. Satırı sildiğinizi ve satırı }eklediğinizi gösterir }\n. Aslında olan budur, ama kavramsal olarak olan şey bu değildir , bu yüzden kafa karıştırıcı olabilir.


2
Aynı şeyi başka yönde de yazabiliriz: Varolan dosyanın sonunda zaten bir satırsonu olan yeni bir satır kaldırırsanız, fark, son satırda, kavramsal olarak değilken, değiştirilmiş olarak da gösterilir. Sonunda bir satırsonu kaldırmak için en az bir iyi neden.
gentiane

3
@gentiane "Yeni bir satır" (yeni bir satır) ve "yeni bir satır" (bir satırın sonunu sınırlayan 1 veya 2 karakter) karıştırıyorsunuz
minexew

@ minexew Hayır, gentiane değil. Belki de "yeni bir çizgi" nin "yeni bir çizgi" ile aynı olduğunu bilmiyorsunuzdur.
İnanılmaz Ocak

3
@TheincredibleJan Cevapta kullanılma biçimleri, iki terimin farklı anlamları vardır. Akıllı eşek olmaya mı çalışıyorsun, ya da olup bitenleri yanlış anlıyor musun bilmiyorum.
minexew

18

Sadece dosyanın sonunda bir satırsonu olmadığını gösterir. Bu bir felaket değil, sadece komut satırında bir fark bakarken bir tane olmadığını açıkça belirtmek için bir mesaj.


10

Bu sözleşmenin hayata geçirilmesinin nedeni, UNIX benzeri işletim sistemlerinde, yeni satır karakteri bir satır sonlandırıcısı ve / veya mesaj sınırı olarak ele alınmasıdır (buna işlemler, satır arabelleğe alma, vb. Dahildir).

Örneğin, yalnızca yeni satır karakteri olan bir dosyanın tek, boş bir satır olarak değerlendirildiğini düşünün. Tersine, sıfır bayt uzunluğundaki bir dosya aslında sıfır satırlı boş bir dosyadır. Bu, wc -lkomuta göre onaylanabilir .

Bu davranış tamamen mantıklıdır, çünkü \nkarakter bir satır sonlandırıcıdan ziyade bir satır ayırıcıysa, boş bir metin dosyası ile tek bir boş satır içeren bir metin dosyası arasında ayrım yapmanın başka bir yolu olmayacaktır . Bu nedenle, geçerli metin dosyaları her zaman yeni satır karakteri ile bitmelidir. Tek istisna, metin dosyasının boş olması amaçlanıyorsa (satır yok).


1
Neden -2'ye indirildim? Sadece diğer cevapların belirttiklerini doğrulamakla kalmadım (yani standart UNIX tabanlı araçlar satırlar için bir sonlandırıcı olarak yeni bir satır beklemektedir), aynı zamanda boş bir dosyayı tek bir boş satırdan ayırmanın hiçbir yolu olmadığına da dikkat çekti. . "Mesajın önemi nedir ve bize ne anlatmaya çalışıyor?"
Leslie Krause

Sizi küçümsemedim, ancak bu yanıt Unix tipi sistemlere özgü gibi görünüyor, çünkü sadece bir satırsonu sadece satırsonu karakteri olduğunda geçerlidir. Burada geçerli olduğu açık değildir. Ayrıca, dosya yalnızca boş bir satırdan oluşuyorsa uyarı işe yaramaz gibi görünür. Ancak Stackoverflow kaçıyorum çünkü insanlar genellikle bir açıklama yapmadan iner.
user34660

9

Önceki yanıtlarda görmediğim bir şey var. Satır sonu olmadığına dair uyarı, dosyanın bir kısmı kesildiğinde uyarı olabilir. Eksik verilerin bir belirtisi olabilir.


Genel olarak iyi bir nokta, ama bu özel soru bağlamında bunun mantıklı olduğunu düşünmüyorum.
cst1992

@ cst1992 Stackoverflow'daki yanıtların olabildiğince yararlı olması, yani tüm olasılıklara uygulanması gerektiği anlamına gelir. Soru kısa ve önerdiğim olasılığı nerede hariç tuttuğunu göremiyorum.
user34660

7

Temel sorun, satırı tanımladığınız ve satır sonu karakter dizisinin satırın bir parçası olup olmadığıdır. UNIX tabanlı editörler (VIM gibi) veya araçlar (Git gibi), satır sonlandırıcı olarak EOL karakter dizisini kullanır, bu nedenle satırın bir parçasıdır. C ve Pascal'da noktalı virgül (;) kullanımına benzer. C noktalı virgülünde ifadeleri sonlandırır, Pascal'da bunları ayırır.


4

Bu aslında bir soruna neden olur, çünkü satır sonları kirli dosyalarda herhangi bir değişiklik yapmadan otomatik olarak değiştirilir. Çözünürlük için bu gönderiye bakın.

git LF yerine CRLF koymak


3

Kaynak dosyalar genellikle araçlar tarafından birleştirilir (C, C ++: başlık dosyaları, Javascript: bundlers). Yeni satır karakterini atlarsanız, kötü hatalar (bir kaynağın son satırı bir sonraki kaynak dosyasının ilk satırı ile birleştirilir) tanıtabilirsiniz. Umarım tüm kaynak kodu concat araçları zaten birleştirilmiş dosyalar arasına yeni bir satır ekler ama bu her zaman böyle görünmüyor.

Sorunun temel noktası - çoğu dilde, yeni satırların semantik anlamı vardır ve dosya sonu, yeni satır karakteri için dil tanımlı bir alternatif değildir. Bu yüzden her ifadeyi / ifadeyi sonuncusu da dahil olmak üzere yeni satır karakteriyle sonlandırmalısınız.


1
C / C ++ 'da tüm projenizi tek bir satıra yazabilirsiniz. Yeni satıra gerek yok.
İnanılmaz Ocak

Sen olabilir Bir kullanmak istemiyorsanız ... tek satırda da tüm projeyi yazma //kod ortasında tarzı yorumunu.
Doug Coburn

2

Orijinal dosyanızın muhtemelen yeni satır karakteri yok.

Ancak, linux'daki gedit gibi bazı editörler sessizce dosya sonuna satırsonu ekler. Bu tür editörleri kullanırken bu mesajdan kurtulamazsınız.

Bu sorunun üstesinden gelmeye çalıştığım şey, visual studio kod düzenleyicisiyle dosyayı açmak

Bu düzenleyici son satırı açıkça gösterir ve satırı istediğiniz gibi silebilirsiniz.


0

Değeri için, bir Mac üzerinde bir IntelliJ projesi oluşturduğumda ve sonra projeyi Windows makineme taşıdığımda bununla karşılaştım. Her dosyayı el ile açmak ve IntelliJ penceresinin sağ alt kısmındaki kodlama ayarını değiştirmek zorunda kaldım. Muhtemelen bu soruyu okuyan ama bana birkaç saat işten kurtarabilecek herhangi bir şey olmasa ...

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.