2008-09-23 13 views
46

J'ai un groupe (des centaines) de fichiers qui sont censés avoir des fins de ligne Unix. Je soupçonne fortement que certains d'entre eux ont des fins de ligne Windows, et je veux comprendre par programme ceux qui le font.Comment déterminer la fin de ligne d'un fichier

Je sais que je peux simplement exécuter

flip -u
ou quelque chose de similaire dans un script pour tout convertir, mais je veux être en mesure d'identifier les fichiers qui doivent d'abord changer.

Répondre

28

Vous pouvez utiliser grep

egrep -l $'\r'\$ * 
+0

Notez simplement: la commande ci-dessus nécessite d'être exécuté à partir de bash. – tzot

+3

pour une raison quelconque, lorsque j'exécute cette commande dans un shell MacOS X, j'obtiens une liste de tous les fichiers du répertoire. Même celui que je viens de générer avec "echo" test "> torderform6.cpp". Une idée de ce qui pourrait aller mal? –

+7

Il liste juste tous les fichiers dans le dossier pour moi sur Ubuntu. – rjmunro

0

Windows utilise char 13 & 10 pour la fin de la ligne, unix seulement l'un d'eux (je ne me souviens pas lequel). Donc, vous pouvez remplacer char 13 & 10 pour char 13 ou 10 (celui qui utilise unix).

64

Vous pouvez utiliser l'outil file, qui vous indiquera le type de fin de ligne. Ou, vous pouvez simplement utiliser dos2unix -U qui va tout convertir en fins de ligne Unix, indépendamment de ce qu'il a commencé avec.

+4

Le fichier n'affiche pas la fin de la ligne. Ex. : "fichier .bashrc => .bashrc: texte anglais ASCII" Besoin de touches supplémentaires? –

+7

@Fedir: Oui, c'est juste que si le fichier a des terminaisons de ligne LF régulières, alors il n'imprimera aucune sortie.Mais si le fichier a CRLF, CR nu, ou des fins de ligne mixtes, il vous le dira. –

+2

Ne fonctionnait pas pour moi sur un script Perl CRLF seulement sur OS X. Peut-être une extension GNU? –

3

Unix utilise un octet, 0x0A (LineFeed), tandis que Windows utilise deux octets, 0x0D 0x0A (retour chariot, saut de ligne).

Si vous ne voyez jamais un 0x0D, c'est très probablement Unix. Si vous voyez des paires 0x0D 0x0A, c'est très probablement MSDOS.

14

Quelque chose le long des lignes de:

perl -p -e 's[\r\n][WIN\n]; s[(?<!WIN)\n][UNIX\n]; s[\r][MAC\n];' FILENAME 

si une partie de cette expression rationnelle peut-être besoin de raffinage et le nettoyage.

Cela produira votre fichier avec WIN, MAC ou UNIX à la fin de chaque ligne. Bon si votre fichier est en quelque sorte un désordre terrible (ou un diff) et a des fins mixtes.

+0

Travaillé pour moi sur Ubuntu, la réponse acceptée semble juste lister tous les fichiers –

+0

Ne fonctionne pas pour moi, donne: 'Unmatched) dans regex; marqué par <- ICI en m/(? <! WIN) <- ICI \ n/at -e ligne 1. ' – moshen

+0

vous devez remplacer le < par' <' – Joseph

0

Lorsque vous savez quels fichiers ont des fins de ligne Windows (0x0D 0x0A ou \r \n), que ferez-vous avec ces fichiers? Je suppose que vous les convertirez en extrémités de ligne Unix (0x0A ou \n). Vous pouvez convertir le fichier avec les fins de ligne Windows dans les fins de ligne Unix avec sed utilitaire, il suffit d'utiliser la commande suivante:

$> sed -i 's/\r//' my_file_with_win_line_endings.txt 

Vous pouvez le mettre dans le script comme ceci:

#!/bin/bash 

function travers() 
{ 
    for file in $(ls); do 
     if [ -f "${file}" ]; then 
      sed -i 's/\r//' "${file}" 
     elif [ -d "${file}" ]; then 
      cd "${file}" 
      travers 
      cd .. 
     fi 
    done 
} 

travers 

Si vous l'exécutez à partir de votre racine dir avec des fichiers, à la fin vous serez sûr que tous les fichiers sont avec des fins de ligne Unix.

4

Voici la réponse la plus sûre. Stimms répondre à compte doesn pour les sous-répertoires et les fichiers binaires

find . -type f -exec file {} \; | grep "CRLF" | awk -F ':' '{ print $1 }' 
  • Utilisez file pour trouver le type de fichier. Ceux avec CRLF ont des caractères de retour de Windows. La sortie de file est délimitée par un : et le premier champ est le chemin du fichier.
+0

En effet la manière la plus sûre. Pour convertir seulement tous les fichiers trouvés il suffit de lancer 'find. -type f -exec fichier {} \; | grep "CRLF" | awk -F ':' '{print $ 1}' | xargs flip -ub' après. – pixelbrackets

+2

La plupart des failsafe ne l'est pas - 'file' ne dit pas toujours" CRLF "dans sa sortie, cela dépend du type de fichier. J'ai découvert que pour les fichiers SVG - contenant du texte comme des fichiers en clair - 'file' ne mentionne pas le type de fin de ligne utilisé. Ce script n'est donc pas un type de fichier agnostique. Je dis juste. Dans le cas contraire ressemble à un one-liner sain, la limitation susmentionnée non-résistante. – amn