2065 votes

Pourquoi les fichiers à la fin avec un retour à la ligne?

Je suppose que tout le monde connaît l'adage qui dit que tous les fichiers texte doit se terminer par un saut de ligne. J'ai connu de cette "règle" pendant des années, mais je me suis toujours demandé: pourquoi?

1945voto

Konrad Rudolph Points 231505

Il y a au moins un dur avantage de cette directive, lorsque l'on travaille sur un émulateur de terminal: Tous les outils Unix attendre la présente convention et de travailler avec elle. Par exemple, lors de la concaténation de fichiers avec l' cat, un fichier terminé par un saut de ligne aura un effet différent que l'autre sans:

$ more a.txt
foo$ more b.txt
bar
$ more c.txt
baz
$ cat *.txt
foobar
baz

Et, comme l'exemple précédent le montre aussi, lors de l'affichage du fichier sur la ligne de commande (par ex. via l' more), un retour à la ligne terminée par le fichier de résultats dans un affichage correct. Un mal résilié fichier peut être déformé (deuxième ligne).

Pour des raisons de cohérence, il est très utile de suivre cette règle – sinon, va engager des travaux supplémentaires lorsque vous traitez avec la valeur par défaut des outils Unix.

314voto

Bill the Lizard Points 147311

Chaque ligne doit être terminée par un caractère de saut de ligne, y compris la dernière. Certains programmes ont des problèmes de traitement de la dernière ligne d'un fichier si ce n'est pas de saut de ligne en fin.

GCC met en garde sur ce pas parce qu'elle ne peut pas traiter le fichier, mais parce qu'il a en tant que partie de la norme.

La norme du langage C dit Un fichier source qui n'est pas vide prend fin dans un caractère de nouvelle ligne, qui ne doit pas être immédiatement précédée d'une barre oblique inverse.

Puisque c'est un "doit" clause, nous devons émettre un message de diagnostic pour une violation de cette règle.

C'est dans la section 2.1.1.2 du C ANSI 1989 standard. La Section 5.1.1.2 de l'ISO C 1999 la norme (et probablement aussi le C ISO 1990 standard).

Référence: GCC/GNU mail archive.

134voto

Milan Adamovsky Points 132

Cette réponse est une tentative de réponse technique plutôt que de l'opinion.

Si nous voulons être POSIX puristes, nous définissons une ligne comme:

Une séquence de zéro ou plus non <newline> caractères plus une terminaison <newline> caractère.

Source: http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_206

Incomplète en ligne comme:

Une séquence d'une ou plusieurs non- <newline> caractères à la fin du fichier.

Source: http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_195

Un fichier texte:

Un fichier qui contient des caractères organisé en zéro ou plusieurs lignes. Les lignes qui ne contiennent pas de NUL, les personnages et aucun ne peut dépasser {LINE_MAX} octets de longueur, y compris le <newline> caractère. Bien que POSIX.1-2008 date ne fait pas de distinction entre les fichiers texte et les fichiers binaires (voir le standard ISO C), de nombreux utilitaires seulement pour produire de l'prévisible ou de production significative lors de l'utilisation de fichiers texte. La norme des utilitaires qui ont de telles restrictions toujours spécifier "fichiers texte" dans leur STDIN ou des FICHIERS d'ENTRÉE sections.

Source: http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_397

Une chaîne de caractères comme:

Un contigus de la séquence d'octets résilié par et y compris le premier octet null.

Source: http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_396

À partir de cela, alors, on peut en déduire que le seul moment où nous allons potentiellement rencontrer tout type de questions que nous traiterons de la notion de ligne d'un fichier ou d'un fichier en tant que fichier texte (étant qu'un fichier texte est un organisme de zéro ou plusieurs lignes, et une ligne de conduite, nous le savons, doit se terminer avec une <newline>).

Affaire au point: wc -l filename.

De la wc's manuel, nous lisons:

Une ligne est définie comme une chaîne de caractères délimitée par un <newline> caractère.

Quelles sont les implications pour JavaScript, HTML, CSS fichiers alors qu'ils sont de texte des fichiers?

Dans les navigateurs, les Ide modernes, et d'autres applications frontales il n'y a pas de problèmes avec sauter en fin de vie à l'EOF. Les applications s'occupe d'analyser les fichiers correctement. Il a depuis pas tous les Systèmes d'Exploitation conformes à la norme POSIX, de sorte qu'il serait impossible pour les non-OS outils (par exemple, les navigateurs) pour gérer les fichiers conformément à la norme POSIX (ou n'importe quel OS au niveau de la norme).

En conséquence, nous pouvons être relativement confiant que EOL à EOF n'aura quasiment aucun impact négatif au niveau de l'application - peu importe si elle est en cours d'exécution sur un système d'exploitation UNIX.

À ce stade, nous pouvons dire avec confiance que le fait de sauter en fin de vie à EOF est en sécurité lorsque vous traitez avec JS, HTML, CSS côté client. En fait, nous pouvons affirmer que les minifying un de ces fichiers ne contenant pas de <newline> est sûr.

Nous pouvons aller encore plus loin et dire que tant que NodeJS est concernée, elle aussi ne peut pas adhérer à la norme POSIX être qu'il peut s'exécuter en non-conformes à POSIX environnements.

Que nous reste-il alors? Le système de niveau de l'outillage.

Cela signifie que les seuls problèmes qui peuvent survenir sont les outils qui font un effort pour respecter leur fonctionnalité à la sémantique POSIX (par exemple, la définition d'une ligne comme indiqué en wc).

Même si, pas tous les coquillages vous adhérer automatiquement à POSIX. Par exemple pour le Bash n'est pas par défaut de comportement POSIX. Il y a un interrupteur pour l'activer: POSIXLY_CORRECT.

Une réflexion sur la valeur de fin de ligne (EOL étant <newline>: http://www.rfc-editor.org/EOLstory.txt

Rester sur l'outillage de la piste, pour toutes fins utiles, considérons ceci:

Nous allons travailler avec un fichier qui n'a pas de fin de ligne (EOL. De cette écriture le fichier dans cet exemple est un minifiés JavaScript sans EOL.

curl http://cdnjs.cloudflare.com/ajax/libs/AniJS/0.5.0/anijs-min.js -o x.js
curl http://cdnjs.cloudflare.com/ajax/libs/AniJS/0.5.0/anijs-min.js -o y.js

$ cat x.js y.js > z.js

-rw-r--r--  1 milanadamovsky   7905 Aug 14 23:17 x.js
-rw-r--r--  1 milanadamovsky   7905 Aug 14 23:17 y.js
-rw-r--r--  1 milanadamovsky  15810 Aug 14 23:18 z.js

Avis de l' cat de la taille du fichier est exactement la somme de ses parties. Si la concaténation de fichiers JavaScript est un sujet de préoccupation pour les fichiers JS, le plus approprié préoccupation serait de commencer chaque fichier JavaScript avec un point-virgule.

Comme quelqu'un d'autre a mentionné dans ce fil de discussion: que faire si vous souhaitez cat deux fichiers dont la sortie est juste une ligne au lieu de deux? En d'autres termes, cat fait ce qu'il est censé faire.

L' man de cat , ne mentionne que la lecture de l'entrée jusqu'à l'EOF, pas <newline>. Notez que l' -n commutateur d' cat sera également imprimer un non- <newline> résilié la ligne (ou incomplète ligne) comme un line - être que la numérotation commence à 1 (selon l' man.)

-les n lignes de sortie, en commençant à 1.

Maintenant que nous comprenons comment POSIX définit une ligne , ce comportement devient ambigu, ou vraiment, non-conforme.

Comprendre un outil objectif et de la conformité de l'aider à déterminer à quel point il est à la fin des fichiers avec une fin de ligne (EOL. En C, C++, Java (Jar), etc... certaines normes dictent une nouvelle ligne de validité - aucune norme n'existe pour le JS, HTML, CSS.

Par exemple, au lieu d'utiliser wc -l filename on pourrait faire, awk '{x++}END{ print x}' filename , et soyez assuré que la tâche du succès n'est pas mise en péril par un fichier on peut vouloir le processus que nous n'avons pas d'écriture (par exemple, un tiers de la bibliothèque comme le minifiés JS nous curld) - à moins que notre intention était vraiment de compter les lignes dans l'conforme à POSIX sens.

Conclusion

Il y aura très peu de cas concrets d'utilisation où sauter EOL à EOF pour certains fichiers texte comme les JS, HTML, CSS et aura un impact négatif, si. Si nous nous appuyons sur <newline> être présent, nous sommes en limitant la fiabilité de notre outillage uniquement pour les fichiers que nous auteur et de nous ouvrir à d'éventuelles erreurs introduites par des tiers, fichiers.

Morale de l'histoire: Ingénieur de l'outillage qui n'ont pas la faiblesse de s'appuyer sur EOL à l'EOF.

N'hésitez pas à poster des cas d'utilisation qui s'appliquent à JS, HTML et CSS où l'on peut examiner comment sauter en fin de vie a un effet négatif.

68voto

VonC Points 414372

Elle peut être liée à la différence entre:

  • fichier texte (chaque ligne est censé prendre fin en fin-de-ligne)
  • fichier binaire (il n'y a pas de véritables "lignes" à proprement parler, et la longueur du fichier doit être préservée)

Si chaque ligne ne bout en bout de ligne, cela évite, par exemple, que la concaténation de deux fichiers texte rendrait la dernière ligne de la première manche dans la première ligne de la deuxième.

De Plus, un éditeur peut vérifier à charge si le fichier se termine en bout de ligne, il enregistre dans ses locaux l'option 'fin de vie', et l'utilise lors de l'écriture du fichier.

A quelques années (2005), de nombreux éditeurs (ZDE, Eclipse, Scite, ...) n'a "oublier" de cette finale en fin de vie, ce qui n'était pas très apprécié.
Non seulement cela, mais ils l'ont interprété de cette finale EOL tort, comme "commencer une nouvelle ligne", et de commencer à afficher une autre ligne comme si elle existait déjà.
C'était très visible avec un " bon " fichier texte avec un bon comportement de l'éditeur de texte vim, par rapport à l'ouverture dans l'un de ces éditeurs. Il affiche une ligne supplémentaire en-dessous du dernière ligne du fichier. Vous voyez quelque chose comme ceci:

1 first line
2 middle line
3 last line
4

53voto

Flimm Points 8870

Certains outils s'attendre à ce. Par exemple, wc s'attend à ce que:

$ echo -n "Line not ending in a new line" | wc -l
0
$ echo "Line ending with a new line" | wc -l
1

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X