Comment trouver une fenêtre fin de caractère ligne (EOL)
Question
J'ai plusieurs centaines de Go de données que je dois coller ensemble à l'aide de la pâte unix utilitaire dans Cygwin, mais il ne fonctionnera pas correctement s'il y a des fenêtres de caractères EOL dans les fichiers. Les données peuvent ou non avoir des fenêtres de caractères EOL, et je ne veux pas passer le temps d'exécution dos2unix si je n'ai pas.
Alors ma question est, dans Cygwin, comment puis-je savoir si ces fichiers contiennent des fenêtres caractères EOL CRLF?
Je l'ai essayé de créer des données de test et en cours d'exécution
sed -r 's/\r\n//' testdata.txt
Mais qui semble correspondre indépendamment du fait que dos2unix a été exécuté ou non.
Merci.
La solution
L'utilitaire file(1)
connaît la différence:
$ file * | grep ASCII
2: ASCII text
3: ASCII English text
a: ASCII C program text
blah: ASCII Java program text
foo.js: ASCII C++ program text
openssh_5.5p1-4ubuntu5.dsc: ASCII text, with very long lines
windows: ASCII text, with CRLF line terminators
file(1)
a été optimisé pour essayer de lire aussi peu d'un fichier que possible, de sorte que vous pouvez être chanceux et de réduire considérablement la quantité de disque IO vous devez effectuer lors de la recherche et de fixer les terminateurs CRLF.
Notez que certains cas de CRLF devraient rester en place: captures de SMTP utilisera CRLF. Mais c'est à vous. :)
Autres conseils
Vous pouvez trouver à l'aide file
:
file /mnt/c/BOOT.INI
/mnt/c/BOOT.INI: ASCII text, with CRLF line terminators
CRLF est la valeur significative.
Si vous attendez le code de sortie pour être différent de sed
, il ne sera pas. Il effectuera une substitution ou non en fonction du match. Le code de sortie sera vrai, sauf si il y a une erreur.
Vous pouvez obtenir un code de sortie utilisable à partir grep
, cependant.
#!/bin/bash
for f in *
do
if head -n 10 "$f" | grep -qs $'\r'
then
dos2unix "$f"
fi
done
#!/bin/bash
for i in $(find . -type f); do
if file $i | grep CRLF ; then
echo $i
file $i
#dos2unix "$i"
fi
done
Uncomment "# dos2unix "$ i"" lorsque vous êtes prêt à les convertir.
Merci pour la pointe vers le fichier d'utilisation (1) commande, mais il a besoin d'un peu plus de raffinement. J'ai eu la situation où non seulement les fichiers de texte brut, mais aussi quelques scripts « .sh » avaient le mauvais EOL. Et des rapports « fichiers » eux comme suit quel que soit EOL:
xxx/y/z.sh: application/x-shellscript
l'option "fichier souple -e" était nécessaire (au moins pour Linux):
bash$ find xxx -exec file -e soft {} \; | grep CRLF
Ceci trouve tous les fichiers avec DOS EOL dans le répertoire xxx et subdirs.
grep récursif, d'un filtre de modèle de fichier
grep -Pnr --include=*file.sh '\r$' .
nom de fichier de sortie, le numéro de la ligne et la ligne elle-même
./test/file.sh:2:here is windows line break
Comme indiqué au-dessus des travaux de solution « fichier ». Peut-être que l'extrait de code suivant peut aider.
#!/bin/ksh
EOL_UNKNOWN="Unknown" # Unknown EOL
EOL_MAC="Mac" # File EOL Classic Apple Mac (CR)
EOL_UNIX="Unix" # File EOL UNIX (LF)
EOL_WINDOWS="Windows" # File EOL Windows (CRLF)
SVN_PROPFILE="name-of-file" # Filename to check.
...
# Finds the EOL used in the requested File
# $1 Name of the file (requested filename)
# $r EOL_FILE set to enumerated EOL-values.
getEolFile() {
EOL_FILE=$EOL_UNKNOWN
# Check for EOL-windows
EOL_CHECK=`file $1 | grep "ASCII text, with CRLF line terminators"`
if [[ -n $EOL_CHECK ]] ; then
EOL_FILE=$EOL_WINDOWS
return
fi
# Check for Classic Mac EOL
EOL_CHECK=`file $1 | grep "ASCII text, with CR line terminators"`
if [[ -n $EOL_CHECK ]] ; then
EOL_FILE=$EOL_MAC
return
fi
# Check for Classic Mac EOL
EOL_CHECK=`file $1 | grep "ASCII text"`
if [[ -n $EOL_CHECK ]] ; then
EOL_FILE=$EOL_UNIX
return
fi
return
} # getFileEOL
...
# Using this snippet
getEolFile $SVN_PROPFILE
echo "Found EOL: $EOL_FILE"
exit -1
Vous pouvez utiliser l'option -i de dos2unix pour obtenir des informations sur les sauts de ligne Mac DOS Unix (dans cet ordre), et BOM texte / binaire sans convertir le fichier.
$ dos2unix -i *.txt
6 0 0 no_bom text dos.txt
0 6 0 no_bom text unix.txt
0 0 6 no_bom text mac.txt
6 6 6 no_bom text mixed.txt
50 0 0 UTF-16LE text utf16le.txt
0 50 0 no_bom text utf8unix.txt
50 0 0 UTF-8 text utf8dos.txt
Avec le dos2unix drapeau « c » rapportera des fichiers qui seraient convertis, les fichiers OIEau ont avoir des sauts de ligne DOS. Pour signaler tous les fichiers txt avec des sauts de ligne DOS vous pouvez faire ceci:
$ dos2unix -ic *.txt
dos.txt
mixed.txt
utf16le.txt
utf8dos.txt
Pour convertir uniquement ces fichiers que vous faites simplement:
dos2unix -ic *.txt | xargs dos2unix
Si vous avez besoin d'aller récursive sur les répertoires que vous faites:
find -name '*.txt' | xargs dos2unix -ic | xargs dos2unix
Voir aussi la page de manuel de dos2unix.