2010-05-09 7 views
8

J'ai un tas de fichiers. Certains sont des fins de ligne Unix, beaucoup sont DOS. Je voudrais tester chaque fichier pour voir si est formaté, avant de changer les fins de ligne.Comment détecter les sauts de ligne DOS dans un fichier?

Comment est-ce que je ferais ceci? Y a-t-il un drapeau que je peux tester? Quelque chose de similaire?

+0

Même question que http: // stackoverflow.com/questions/121392/how-to-determine-the-line-ending-of-a-file (sauf celui de 'python' :-) – Jonik

Répondre

6

Vous pouvez rechercher la chaîne pour \r\n. C'est la fin de la ligne de style DOS.

EDIT: Jetez un oeil à this

+0

Oui, c'est le chemin à parcourir. Il n'y a pas de drapeau ou quoi que ce soit. – Jonik

+0

Techniquement, vous recherchez '" \ r \ x0A "'. La plupart des compilateurs utilisent le saut de ligne pour ''\ n'', mais il n'est pas nécessaire d'avoir cette valeur particulière. –

0

dos linebreaks sont \r\n, unix seulement \n. Il suffit donc de rechercher \r\n.

1

En tant que débutant Python complet & juste pour le plaisir, j'ai essayé de trouver une façon minimaliste de vérifier cela pour un fichier. Cela semble fonctionner:

if "\r\n" in open("/path/file.txt","rb").read(): 
    print "DOS line endings found" 

Modifier: simplifiée selon le commentaire de John Machin (pas besoin d'utiliser des expressions régulières).

+0

Ne devriez-vous pas ouvrir le fichier avec "rb"? –

+0

Hmm, ma première pensée était non, parce que nous traitons des fichiers * text * ... Mais faites-vous référence à ceci: "Le mode par défaut est d'utiliser le mode texte, qui peut convertir les caractères \ n 'en plate-forme ... représentation spécifique sur l'écriture et retour sur la lecture. " (http://docs.python.org/library/functions.html#open)? Je n'étais pas au courant de telles conversions - peut-être que "rb" devrait être utilisé pour que cela fonctionne sur des systèmes non-Unix. – Jonik

+2

're.search()' n'est pas minimaliste; c'est OVERKILL; utilisez '" \ r \ n "en open (...). read()'. Il n'y a pas de "peut-être" à propos de l'utilisation de "" rb "'; c'est un impératif. –

3

(Python 2 seulement :) Si vous voulez juste lire des fichiers texte, soit DOS ou formaté Unix, cela fonctionne:

print open('myfile.txt', 'U').read() 

C'est, lecteur de fichiers « universel » de Python utilisera automatiquement tous les différents marqueurs de fin de ligne, en les traduisant par "\ n".

http://docs.python.org/library/functions.html#open

(Merci poignée!)

+1

Eh bien, je vais vouloir les éditer dans vim. Je voudrais que cette ligne se termine une fois et qu'elle soit validée, par fichier. – chiggsy

+2

Cela changera DOS CRLF destructivement à Unix LF sur tous les fichiers dans le répertoire courant: perl -p0i -e 's/\ r \ n/\ n/g' * Je l'ai tapé tant de fois mon les doigts l'ont mémorisé :) – johntellsall

+0

@chiggsy installez le paquetage dos2unix, et exécutez plutôt la commande dos2unix sur les fichiers. – nos

22

Python peut détecter automatiquement quelle convention nouvelle ligne est utilisée dans un fichier, grâce au "mode newline universel" (U), et vous pouvez accéder à Python deviner par l'attribut newlines des objets fichier:

f = open('myfile.txt', 'U') 
f.readline() # Reads a line 
# The following now contains the newline ending of the first line: 
# It can be "\r\n" (Windows), "\n" (Unix), "\r" (Mac OS pre-OS X). 
# If no newline is found, it contains None. 
print repr(f.newlines) 

Cela donne à la fin de retour à la ligne de la première ligne (Unix, DOS, etc.), si tout. Comme John M. l'a souligné, si par hasard vous avez un fichier pathologique qui utilise plus d'un codage de nouvelle ligne, f.newlines est un tuple avec tous les codages de nouvelle ligne trouvés jusqu'à présent, après avoir lu plusieurs lignes.

Référence: http://docs.python.org/2/library/functions.html#open

Si vous voulez juste convertir un fichier, vous pouvez simplement faire:

with open('myfile.txt', 'U') as infile: 
    text = infile.read() # Automatic ("Universal read") conversion of newlines to "\n" 
with open('myfile.txt', 'w') as outfile: 
    outfile.write(text) # Writes newlines for the platform running the program 
+1

-1 Cela s'appelle' newlines' (pluriel) et ce n'est pas un encodage. Ce que vous avez montré est comment trouver quoi (si quelque chose) termine la première ligne (le cas échéant). Votre commentaire est incorrect: il n'inclut pas le cas où la première ligne et la seule ligne ne sont pas terminées (et donc 'newlines' se réfère à' None'). En outre, il suppose que toutes les lignes sont terminées de la même manière. Les concaténations de fichiers de différentes fins de ligne ne sont pas inconnues. Dans l'application de l'OP de standardiser sur une fin de ligne, il devra lire TOUT le fichier d'entrée (et TOUS les docs, en particulier où il mentionne «tuple»). –

+2

@John: Allez: -1 pour une réponse qui mentionne les utiles «newlines», mais seulement avec une faute de frappe? Ou pour les fichiers pathologiques concaténés à partir de fichiers avec différentes conventions de nouvelle ligne? L'affiche originale mentionnait "fichiers d'Unix ou DOS", pas de tels fichiers étranges! – EOL

+0

@John: Vos informations sur f.newlines renvoyant un tuple dans le cas d'une convention de nouvelle ligne mixte sont intéressantes. Je l'ai ajouté à la réponse. – EOL

0

En utilisant grep & bash:

grep -c -m 1 $'\r$' file 

echo $'\r\n\r\n' | grep -c $'\r$'  # test 

echo $'\r\n\r\n' | grep -c -m 1 $'\r$' 
Questions connexes