grep para buscar archivos que contengan ^ M (retorno de carro de Windows)


70

Yo uso Linux Hay un molesto ^ M (retorno de carro de Windows) en algún lugar oculto en miles de archivos de configuración, y tengo que encontrarlo, porque hace que el servidor falle.

¿Cómo encuentro ^ M entre una jerarquía de directorios llena de archivos de configuración?

Creo que no puedo ingresar ^ M en la línea de comando bash. Pero lo tengo en un archivo de texto que llamé m.txt



Windows sería ^ M ^ J
barlop

2
"No puedo ingresar ^ M en la línea de comando bash". Sí tu puedes. Prueba control-V Control-M
Hennes

Respuestas:


89
grep -r $'\r' *

Úselo -rpara búsqueda recursiva y $''para escape estilo c en Bash.

Más aún, si está seguro de que es un archivo de texto, entonces debería ser seguro ejecutarlo

tr -d $'\r' < filename

para eliminar todo \ren un archivo.

Si usa GNU sed, -ipuede realizar la edición en el lugar, por lo que no necesitará escribir de nuevo:

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

10
@Nicolas: Puede ingresar un ^ M en la línea de comando presionando ^ V ^ M, pero es mejor usarlo $'\r'.
Dennis Williamson

Genial, funciona! Gracias por el truco ^ V ^ M también :-)
Nicolas Raoul

55
Bajo Cygwin, se necesita -U para que esto funcione. Y -n le dirá el número de línea: grep -r -U -n -e $ '\ r'
Rainer Blome

44
Agregue una -l al comando grep para ver los nombres de los archivos. De lo contrario, podría ser bombardeado con líneas coincidentes.
Brendan Byrd

1
@uprego no estoy seguro si los comprende ahora, pero para su información y otros, busque $'leer el primer hit en la página de manual bash(1), básicamente, puede verlo como si estuviera escribiendo una cadena literal C. En cuanto al command < filenameuso de <o >se llama redirección , esta es la primera vez que veo a alguien llamarlo mayor expresión . Buscar REDIRECTIONen bash(1).
livibetter

12

Cuando lo intenté, me di cuenta de que funcionaba, pero las líneas se imprimían en blanco. Agregue la opción:

--color=never

Si tiene este problema, creo que son los caracteres de escape para resaltar el color que interfieren con el \rpersonaje.


2

Si su servidor no tiene un shell bash, una alternativa es usar la -fopción grep, en combinación con un archivo preparado que contenga \r.

Para crear el archivo:

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

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

Para hacer realmente la búsqueda

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

o puedes ser un poco vago y simplemente escribir *,

$ grep -f /tmp/cr *

La opción on se usa para especificar un archivo que contiene patrones para que coincidan, uno por línea. En este caso solo hay un patrón.-f filenamegrep


1

Para usar grep en los caracteres de fin de línea, supongo que debe decirle a grep que el archivo es binario.

-l (letra L) es para imprimir solo el nombre del archivo

-P es para regexp perl (entonces \ x0d se transforma a \ r o ^ M)

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

1

Si entiendo su pregunta correctamente, lo que realmente quiere es normalizar todas las terminaciones de línea al \x0aestándar Unix LF ( ). Eso no es lo mismo que simplemente eliminar ciegamente los CR ( \xod).

Si tiene algunos archivos Mac que usan solo CR para líneas nuevas, destruirá esos archivos. (Sí, se supone que las Mac usan LF desde hace casi 20 años, pero todavía hay (en 2019) muchas aplicaciones de Mac que usan solo CR).

Puede usar el \R escape de salto de línea de Perl para reemplazar cualquier tipo de línea nueva con \n.

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

Esto reemplazaría en el lugar cualquier tipo de salto de línea con \nin $your_file, manteniendo una copia de seguridad del archivo original ${your_file}.bak.


0

Si está en una Mac y usa homebrew , puede hacer:

brew install tofrodos
fromdos file.txt

para eliminar todos los retornos de carro de Windows de file.txt

Para volver a los retornos de carro de Windows,

todos file.txt

para buscar en una carpeta y limpiar todos los archivos procedentes de DOS, ejecute este comando: buscar. -type f -name "* .java" | xargs fromdos
Taiko

0

En el estilo de expresión regular, varias líneas nuevas:

Windows (CR LF)
\r\n

Unix (LF)
\n

Como la \r\nsecuencia es bastante única, ¿creo que deberías poder buscarla de esa manera?

Para empeorar las cosas, Macs solía tener '\ r' en lugar de nueva línea. No puedo verificar esto, pero no creo que las generaciones de MacOSX lo hagan más.

Macs más antiguos (CR)
\r


En el directorio que contiene m.txt, grep "\r\n" *no da ningún resultado. Ningún resultado para egrep -e "\r\n" *nigrep -E "\r\n" *
Nicolas Raoul

@nicolas ah, entendí mal ... querías decir CR solo \rmi mal. Una nueva línea de Windows completa es de hecho \r\no CRLF
Jeff Atwood

0

Siguiendo las respuestas anteriores, el método 'tr' es bueno:

533 $ if [[-n " tr -cd "\r" <~/.bashrc"]]; entonces echo "DOS"; si no echo "UNIX"; fi

UNIX

534 $ if [[-n " tr -cd "\r" <dosfile.txt"]]; entonces echo "DOS"; si no echo "UNIX"; fi

DOS

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.