grep pour trouver les fichiers contenant ^ M (retour chariot Windows)


72

J'utilise Linux. Il y a un embêtant ^ M (retour de voiture Windows) caché quelque part dans des milliers de fichiers de configuration, et je dois le trouver, car le serveur échouera.

Comment trouver ^ M dans une hiérarchie de répertoires contenant des fichiers de configuration?

Je pense que je ne peux pas entrer ^ M sur la ligne de commande bash. Mais je l'ai dans un fichier texte que j'ai appelé m.txt



les fenêtres seraient ^ M ^ J
barlop

3
"Je ne peux pas entrer ^ M sur la ligne de commande bash". Oui, vous pouvez. Essayez control-V Control-M
Hennes

Réponses:


92
grep -r $'\r' *

Utilisez cette -roption pour la recherche récursive et $''pour l’évasion de type C dans Bash.

Plus, si vous êtes sûr que c'est un fichier texte, alors il devrait être sécuritaire de l'exécuter

tr -d $'\r' < filename

tout supprimer \rdans un fichier.

Si vous utilisez GNU sed, vous -ipouvez effectuer des modifications sur place, de sorte que vous n’aurez pas à écrire:

sed $'s/\r//' -i filename

10
@ Nicolas: Vous pouvez entrer un ^ M sur la ligne de commande en appuyant sur ^ V ^ M, mais il est préférable de l'utiliser $'\r'.
Dennis Williamson

Génial, ça marche! Merci pour le tour ^ V ^ M aussi :-)
Nicolas Raoul

5
Sous Cygwin, -U est nécessaire pour que cela fonctionne. Et -n vous dira le numéro de ligne: grep -r -U -n -e $ '\ r'
Rainer Blome le

4
Ajoutez un -l à la commande grep pour afficher uniquement les noms de fichiers. Sinon, vous pourriez être bombardés avec des lignes correspondantes.
Brendan Byrd

1
@uprego ne sais pas si vous les comprenez maintenant, mais les fyi et autres, cherchez $'le premier hit dans la page de manuel bash(1), vous pouvez le voir comme si vous écriviez une chaîne littérale en C. En ce qui concerne le command < filename, l'utilisation de <ou >s'appelle la redirection , c'est la première fois que je vois quelqu'un l'appeler une expression plus grande . Rechercher REDIRECTIONdans bash(1).
livibetter

12

Quand j'ai essayé, je pouvais dire que c'était en quelque sorte un travail, mais les lignes imprimaient en blanc. Ajouter dans l'option:

--color=never

Si vous avez ce problème, je pense que ce sont les caractères d'échappement pour la mise en surbrillance des couleurs qui interfèrent avec le \rpersonnage.


2

Si votre serveur n’a pas de shell bash, vous pouvez également utiliser l’ -foption on grep, associée à un fichier préparé \r.

Pour créer le fichier:

$ echo -ne '\r' > /tmp/cr                    --or--                   $ printf '\r' > /tmp/cr

$ od -c /tmp/cr
0000000  \r
0000001

Effectuer la recherche

$ grep -f /tmp/cr *.html *.php *.asp *.whatever

ou vous pouvez être un peu paresseux et tapez juste *,

$ grep -f /tmp/cr *

L' option on est utilisée pour spécifier un fichier contenant des modèles à faire correspondre, un par ligne. Dans ce cas, il n'y a qu'un seul motif.-f filenamegrep


2

Si je comprends bien votre question, ce que vous voulez réellement, c'est normaliser toutes les fins de lignes au \x0astandard Unix LF ( ). Ce n'est pas la même chose que retirer aveuglément des CR ( \x0d).

Si vous avez des fichiers Mac autour desquels vous utilisez uniquement CR pour les nouvelles lignes, vous les détruirez. (Oui, les Mac sont censés utiliser la LF depuis près de 20 ans, mais il existe encore (en 2019) de nombreuses applications Mac utilisant uniquement la technologie CR).

Vous pouvez utiliser l' \R échappement de saut de ligne de Perl pour remplacer n'importe quel type de nouvelle ligne \n.

perl -i.bak -pe 's/\R/\n/g' $your_file

Ceci remplacerait toute rupture de ligne \nin- situ sur place $your_file, en conservant une sauvegarde du fichier d'origine ${your_file}.bak.


1

Pour utiliser grep sur les caractères de fin de ligne, je suppose que vous devez indiquer à grep que le fichier est binaire.

-l (lettre L) sert à imprimer uniquement le nom de fichier

-P est pour l'expression rationnelle perl (donc \ x0d est transformé en \ r ou ^ M)

grep -l --binary -P '\x0d' *

0

Si vous utilisez un homebrew sur Mac , vous pouvez effectuer les opérations suivantes:

brew install tofrodos
fromdos file.txt

supprimer tous les retours chariot de Windows du fichier.txt

Pour revenir aux retours chariot de Windows,

todos file.txt

pour rechercher dans un dossier et nettoyer tous les fichiers provenant de dos, exécutez la commande suivante: find. -type f -name "* .java" | xargs fromdos
Taiko

0

Dans le style de l'expression régulière, diverses nouvelles lignes:

Windows (CR LF)
\r\n

Unix (LF)
\n

Étant donné que la \r\nséquence est assez unique, je pense que vous devriez pouvoir la rechercher de cette façon?

Pour aggraver les choses, les Mac n’avaient que «\ r» à la place de Newline. Je ne peux pas le vérifier, mais je ne pense pas que les générations MacOSX le fassent davantage.

Macs plus anciens (CR)
\r


Dans le répertoire qui contient m.txt, grep "\r\n" *ne donne aucun résultat. Aucun résultat ni pour egrep -e "\r\n" *nigrep -E "\r\n" *
Nicolas Raoul

@ nicolas ah, j'ai mal compris… tu voulais dire que CR était seulement \rmon mauvais. Une nouvelle ligne de fenêtres complète est en effet \r\nou CRLF
Jeff Atwood

0

Suite aux réponses précédentes, la méthode 'tr' est bonne:

533 $ si [[-n " tr -cd "\r" <~/.bashrc"]]; puis echo "DOS"; sinon echo "UNIX"; Fi

UNIX

534 $ si [[-n " tr -cd "\r" <dosfile.txt"]]; puis echo "DOS"; sinon echo "UNIX"; Fi

DOS

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.