Dosyanın sonuna yeni bir satır eklemenin amacı nedir?


166

Bazı derleyiciler (özellikle C veya C ++ olanlar) size şu konularda uyarılar verir:

No new line at end of file

Bunun yalnızca C programcıları için bir sorun olacağını düşünmüştüm, ancak Github işlem görünümünde bir mesaj görüntülüyor:

\ No newline at end of file

PHP dosyası için.

Ben açıklandığı önişlemci olayını anlıyorum bu iş parçacığı , ancak bu PHP ile ne ilgisi var? Aynı include()şey mi, yoksa \r\nvs \nkonuyla mı ilgili?

Dosyanın sonunda yeni bir satıra sahip olmanın anlamı nedir?



2
İnsanları kızdırmak için.
Andrew,

3
Eğer catdosyaysanız, bir sonraki satır yeni satır ile bitmezse son "satıra" eklenecektir.
Aaron Franke

Yanıtlar:


185

Bir dosyanın sonuna fazladan bir yeni satır eklemekle ilgili değil, olması gereken yeni satırı kaldırmamakla ilgili.

Unix'in altındaki bir metin dosyası , her biri newline karakteriyle ( ) biten bir dizi satırdan oluşur . Boş olmayan ve yeni bir satırla bitmeyen bir dosya bu nedenle bir metin dosyası değildir.\n

Metin dosyaları üzerinde çalışması gereken programlar, yeni bir satır ile bitmeyen dosyalarla başa çıkamaz; Örneğin, tarihsel Unix yardımcı programları, metni son satırdan sonra görmezden gelebilir. GNU yardımcı programları, metin dışı dosyalarla iyi bir şekilde davranma politikasına sahiptir ve diğer birçok modern yardımcı programda da geçerlidir, ancak yine de son bir yeni satırda eksik dosyalarda garip davranışlarla karşılaşabilirsiniz.

GNU diff'de, karşılaştırılmakta olan dosyalardan biri yeni bir satırla bitiyorsa diğeri ile bitmiyorsa, bu gerçeğe dikkat etmek önemlidir. Diff satır yönelimli olduğu için, dosyalardan biri için yeni bir satır depolamakla, diğerleri için değil - bu yeni satırlar diff dosyasındaki her satırın nerede başladığını ve bittiğini belirtmek için gereklidir . Bu nedenle diff, bu yeni metni \ No newline at end of file, yeni satırda bitmeyen bir dosyayı, yapılan dosyadan ayırt etmek için kullanır .

Bu arada, bir C bağlamında, bir kaynak dosya benzer şekilde bir dizi satırdan oluşur. Daha doğrusu, bir çeviri birimi, her biri yeni satır karakteriyle bitmesi gereken bir dizi satır olarak tanımlanan bir uygulamada görülür ( n1256 §5.1.1.1). Unix sistemlerde, haritalama basittir. DOS ve Windows'ta, her bir CR LF dizisi ( \r\n) yeni bir satırla eşleştirilir ( \n; bu işletim sistemlerinde metin olarak açılan bir dosyayı okurken her zaman olan şey budur). Yeni satır karakterine sahip olmayan, bunun yerine sabit veya değişken boyutlu kayıtlara sahip birkaç işletim sistemi var; Bu sistemlerde, dosyalardan C kaynağına eşleme bir\nHer kaydın sonunda. Bu, unix ile doğrudan alakalı olmasa da, rekor temelli metin dosyaları olan bir sisteme son satırını kaçıran bir C kaynak dosyasını kopyalarsanız, o zaman tekrar kopyalarsanız, tamamlanmamış demektir. son satır ilk dönüşümde kesildi veya ters dönüşüm sırasında üzerine konulan fazladan bir yeni satır.

¹ Örnek: GNU sıralamalarının çıkışı her zaman yeni bir satırla bitiyor. Bu nedenle, dosya fooson satırını kaçırıyorsa, bu sort foo | wc -craporun bir karakterden daha fazla olduğunu göreceksiniz cat foo | wc -c.


Her biri yeni bir satır karakteriyle (n1256 §5.1.1.1) sona ermesi gereken "... satır dizisi" ile ilgili olarak - - Daha yeni bir C11dr N1570'i tekrar görüntülerken, belki başkaları için destek bulamadı: "Boş olmayan bir kaynak dosyası, böyle bir ekleme yapılmadan önce hemen bir ters eğik çizgi karakterinden önce gelmeyecek olan yeni bir satır karakteriyle bitecektir." §5.1.1.2 2, fakat bu, spesifikasyonlarla sınırlı olarak görünmektedir.
chux,

@chux Bu cümle n1256'da da var. Son satır yeni satır karakteriyle bitmelidir. Son satır olmayan satırlar açıkça, satırın bittiğini ve bir sonraki satırın başladığını belirtmek için yeni bir satır karakteriyle bitmelidir. Bu yüzden her satır yeni satır karakteriyle bitmelidir.
Gilles,

Hmmm, Bana göre, bu satırda "" Bir kaynak dosyası ... birleştirme işlemi gerçekleşiyor. "Genel olarak dosyaları değil, dosya ekleme düşünceleriyle sınırlandırılabilir. Yine de, birinin nasıl başka türlü görüntüleyebileceğini görüyorum. Belki de bir yazı arayacağım Bu odaklanan
chux

> "Yani diff bu özel metni kullanıyor \ Yeni bir satırda bitmeyen bir dosyayı diğer dosyadan ayırt etmek için dosyanın sonunda yeni satır yok." Git bu metni sadece dosyaları karşılaştırırken göstermez. Ancak yeni dosya git'e eklendiğinde bile. Yani bu argüman geçerli değil, sanırım.
Viktor Kruglikov

> "Metin dosyalarında çalışması gereken programlar, yeni bir satırla bitmeyen dosyalarla başa çıkmayabilir" Gereksinimler. Git bu mesajı gösterirse, sebebin kaynak kontrol problemlerinde olması gerektiğini düşünüyorum .
Viktor Kruglikov

41

Sebep değil, yeni bir satır ile bitmeyen dosyaların pratik bir sonucu:

Kullanarak birkaç dosyayı işlemek istiyorsanız ne olacağını düşünün cat. Örneğin, sözcüğü foosatırın başında 3 dosya arasında bulmak isterseniz :

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

Eğer dosya3'teki ilk satır ile başlar foo, ancak dosya2 \nson satırından sonra bir sonlanamazsa , bu olay grep tarafından bulunmaz, çünkü dosya2'deki son satır ve dosya3'teki ilk satır grep tarafından tek satır olarak görünür hat.

Bu yüzden tutarlılık için ve sürprizlerden kaçınmak için dosyalarımı daima yeni bir satırla bitirdim.


Fakat dosyaların birleştirilmesiyle ilgilenmek gitmenin işi midir?
Viktor Kruglikov

Sadece '\n'kedi ameliyatına koymanız gerekmiyor mu ...
Andrew

3
"Bazen dizeleri \nuçlarında boşluk bırakan veya boşluk bırakan dizeleri ekliyorum, bu yüzden işleri tutarlı tutmak için \n _____dizelerimin her iki ucuna da her zaman koyarım." Hayır, orada yapılacak en doğru şey Dizgilerinizin kırpılmasını sağlamak ve sonra onları doğru bir şekilde birleştirmek.
Andrew,

16

İki yönü var:

  1. Yeni bir satırla bitmezse son satırı ayrıştıramayan bazı C derleyicileri vardır. C standardı, bir C dosyasının yeni bir satırla bitmesi gerektiğini (C11, 5.1.1.2, 2.) ve yeni bir satır içermeyen son bir satırın tanımsız davranış (C11, J.2, 2nd item) verdiğini belirtir. Belki de tarihi nedenlerden ötürü, böyle bir derleyicinin bir satıcısı ilk standardın yazıldığı sırada komitenin bir parçasıydı. Böylece GCC tarafından uyarı.

  2. diffprogramlar ( git diffgithub vb. tarafından kullanıldığı gibi) dosyalar arasındaki satır farklarını gösterir. Genellikle bir dosya newline ile bitince genellikle bir mesaj basarlar, çünkü bu farkı görmezsiniz. Aynıydı, ne zaman iki dosya arasındaki tek fark her iki dosyaları gibi görünecektir ipucu olmadan geçtiğimiz satır karakteri varlığı Örneğin diffve cmp(bir çıkış kodu eşitsiz başarı ve dosya toplamlarını dönmek örn üzeri md5sum) eşleşmiyor.


fark programı ile mantıklı
Thamaraiselvam

Farklılıklar gibi sesler sadece daha akıllı olmalı.
Andrew,

@Andrew, hayır, değil. diffvarsa farkları yazdırması bekleniyor. Ve eğer bir dosyada son karakter olarak yeni bir satır varsa, diğerinde yazmamışsa, bu fark çıktıda bir şekilde farkedilmelidir.
maxschlepzig

İkinci ifadeniz doğru. Bununla birlikte, diff görüntüleyicinin \nbaşlamak için "newlines" ( ) göstermesi gerekmez , bunun yerine sadece "new lines" gösterebilir.
Andrew,

10

\ No newline at end of fileEğer aldığım github bir yama sonunda görünen (içinde diffbiçimi , "Birleştirilmiş Biçim" bölümünün sonundaki nota bakınız).

Derleyiciler, dosyanın sonunda yeni bir satır olup olmamasına aldırmaz, ancak git(ve diff/ / patchyardımcı programları) bunları hesaba katmak zorundadır. Bunun birçok nedeni var. Örneğin, bir dosyanın sonuna yeni bir satır eklemeyi veya kaldırmayı unutmak hashsum değerini değiştirebilir ( md5sum/ sha1sum). Ayrıca, dosyalar her zaman program değildir ve son bir \nfark yaratabilir.

Not : C derleyicilerinden gelen uyarı hakkında, geriye dönük uyumluluk amaçları için son bir yeni hat için ısrar ettiklerini sanıyorum. Çok eski derleyiciler bitmiyorsa \n(veya diğer sistem bağımlı hat sonu karakter dizisi) son satırı kabul etmeyebilir .


7
"Sanırım geriye dönük uyumluluk amaçları için son bir yeni hat için ısrar ediyorlar" - Hayır, C standardı zorunlu kıldığı için ısrar ediyorlar .
MestreLion

1
@MestreLion C, C kaynak kodu için son bir yeni satır gerektirir (C11 §5.1.1.2 2). G / Ç metin dosyası için C "Son satırın sonlandırıcı bir yeni satır karakteri gerektirip gerektirmeyeceği, uygulama tanımlı" dır. §7.21.2 2
chux

Kim çok eski derleyiciler kullanıyor? Onları kullanmayı bırak.
Andrew,

1
@MestreLion: Sizce neden C standardı zorunlu kılıyor…
Stéphane Gimenez

@ StéphaneGimenez: Farklı işletim sistemleri arasında tutarlılık, daha iyi uyumluluk ve birlikte çalışabilirlik (POSIX ayrıca '\ n' ile biten çizgileri de tanımlar)
MestreLion

4

POSIX, bu, işletim sistemleri arasındaki uyumluluğu korumak için IEEE tarafından belirtilen bir standartlar kümesidir.

Bunlardan biri, sıfır veya daha fazla karakter içermeyen bir dizi artı bir bitiş yeni satır karakteri olan bir "satır" tanımıdır.

Bu yüzden, bu son satırın gerçek bir "satır" olarak tanınması için, sonlandırıcı yeni bir satır karakterine sahip olması gerekir.

Bu, işletim sistemi araçlarına satır sayımı söylemek ya da dosyanızı ayrıştırmak / ayrıştırmak için yardıma ihtiyacınız varsa önemlidir. PHP'nin bir betik dili olduğu göz önüne alındığında, özellikle ilk günlerinde ve hatta şimdi (hiçbir fikrim / varsayım yok) böyle bir işletim sistemi bağımlılığı vardı.

Gerçekte, çoğu işletim sistemi tam olarak POSIX uyumlu değildir ve insanlar o makineden değil, hatta yeni hatları sonlandırmayı umursamamaktadır. Bu yüzden çoğu şey için ya onun umursadığı, uyardığı ya da sadece son metnin bir kısmı gerçekten bir satır olduğu için her şeyin smorgasbordu.


3

Farklılık tarihini korumanın da bir anlamı var. Bir dosya yeni satır karakteri olmadan bitiyorsa, dosyanın sonuna bir şey eklemek, bu son satırı değiştirdiği için farklı uygulamalar tarafından görüntülenecektir (çünkü \nbuna eklenir).

Bu, git blameve gibi komutlarla istenmeyen sonuçlara neden olabilir hg annotate.


Fark gibi görünüyor sadece daha akıllı olması gerekir.
Andrew,
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.