web-dev-qa-db-fra.com

Comment rechercher des fichiers contenant des fins de ligne (CRLF) avec grep sous Linux?

Je veux rechercher des fichiers contenant des fins de ligne dos avec grep sous Linux. Quelque chose comme ça:

grep -IUr --color '\r\n' .

Ce qui précède semble correspondre au littéral rn, ce qui n’est pas ce qui est souhaité.

La sortie de ceci sera acheminée via xargs en todos pour convertir crlf en lf comme ceci

grep -IUrl --color '^M' . | xargs -ifile fromdos 'file'
113
Tim Abell

Utilisation Ctrl+VCtrl+M pour entrer un caractère de retour à la ligne littéral dans votre chaîne grep. Alors:

grep -IUr --color "^M"

fonctionnera - si le ^M il y a un CR littéral que vous entrez, comme je l'ai suggéré.

Si vous voulez la liste des fichiers, vous voulez ajouter le -l option aussi.

Explication

  • -I ignorer les fichiers binaires
  • -U empêche le grep de supprimer les caractères CR. Par défaut, il le ferait s'il décidait que c'était un fichier texte.
  • -r lit tous les fichiers de chaque répertoire de manière récursive.
110
pjz

grep n'est probablement pas l'outil que vous voulez pour cela. Il imprimera une ligne pour chaque ligne correspondante dans chaque fichier. À moins que vous ne vouliez, par exemple, exécuter todos 10 fois sur un fichier de 10 lignes, grep n'est pas la meilleure solution. En utilisant find pour exécuter le fichier sur chaque fichier de l’arbre, puis en parcourant celui de "CRLF", vous obtiendrez une ligne de sortie pour chaque fichier comportant des fins de ligne de style:

find . -not -type d -exec file "{}" ";" | grep CRLF

vous obtiendrez quelque chose comme:

./1/dos1.txt: ASCII text, with CRLF line terminators
./2/dos2.txt: ASCII text, with CRLF line terminators
./dos.txt: ASCII text, with CRLF line terminators
143
Thomee
49
Steven Penny

Si votre version de grep supporte - P (--Perl-regexp) option, alors

grep -lUP '\r$'

peut être utilisé.

16
Linulin
# list files containing dos line endings (CRLF)

cr="$(printf "\r")"    # alternative to ctrl-V ctrl-M

grep -Ilsr "${cr}$" . 

grep -Ilsr $'\r$' .   # yet another & even shorter alternative
7
yabt

La requête était une recherche ... J'ai un problème similaire ... quelqu'un a soumis des fins de ligne mixtes dans le contrôle de version, nous avons donc maintenant un tas de fichiers avec 0x0d0x0d0x0a fins de lignes. Notez que

grep -P '\x0d\x0a'

trouve toutes les lignes, alors que

grep -P '\x0d\x0d\x0a'

et

grep -P '\x0d\x0d'

ne trouve pas de lignes, il peut donc y avoir quelque chose d '"autre" dans grep en ce qui concerne les motifs de fin de ligne ... malheureusement pour moi!

3
Peter Y

Vous pouvez utiliser la commande de fichier sous unix. Il vous donne l'encodage des caractères du fichier avec les terminaisons de ligne.

$ file myfile
myfile: ISO-8859 text, with CRLF line terminators
$ file myfile | grep -ow CRLF
CRLF  
2

Si, comme moi, votre unix minimaliste n'inclut pas les subtilités telles que la commande fichier, et les barres obliques inverses dans vos expressions (grep) ne coopèrent tout simplement pas, essayez ceci:

$ for file in `find . -type f` ; do
> dump $file | cut -c9-50 | egrep -m1 -q ' 0d| 0d'
> if [ $? -eq 0 ] ; then echo $file ; fi
> done

Les modifications que vous souhaitez apporter à ce qui précède incluent:

  • Ajustez la commande find pour localiser uniquement les fichiers que vous souhaitez analyser.
  • changez la commande dump en od ou tout autre utilitaire de vidage de fichier existant
  • confirmez que la commande cut inclut à la fois les espaces de début et de fin, ainsi que le caractère hexadécimal généré par l'utilitaire dump
  • limiter la sortie de vidage aux 1 000 premiers caractères environ pour plus d'efficacité

Par exemple, quelque chose comme ceci peut fonctionner pour vous en utilisant od au lieu de dump:

 od -t x2 -N 1000 $file | cut -c8- | egrep -m1 -q ' 0d| 0d|0d$'
1
MykennaC