2008-09-16 6 views
94

Quiero buscar archivos que contengan dos terminaciones de línea con grep en Linux. Algo como esto:¿Cómo se buscan archivos que contengan dos finales de línea (CRLF) con grep en Linux?

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

Lo anterior parece coincidir para literal rn que no es lo que se desea.

La salida de este se redirigirá a través xargs en todos para convertir CRLF a LF como este

grep -IUrl --color '^M' . | xargs -ifile fromdos 'file' 
+0

¿Has probado [dos2unix] (http://linux.die.net/man/1/dos2unix)? Arregla las terminaciones de línea automáticamente. – sblundy

+0

No estoy muy seguro, pero iirc hay una diferencia entre citar el patrón dentro de 'y'. Afaik en patrones encerrados en 'las secuencias de escape se interpretan como una cadena adecuada' por lo que '\ r' sería equivalente a "\\ r" y "\ r" no tiene equivalente (al menos en esa notación) con '. – Anticom

+0

Anticom: está en lo correcto en este caso en que la diferencia entre' y 'es irrelevante; sin embargo, en general son distintos ya que 'las cadenas rodeadas son citadas débilmente, y' son citadas con fuerza. Lo más importante que aprovecho es que $ expansiones o '' no se expanden en cadenas débilmente citadas. Véase [bash-hackers en las citas ] (http://wiki.bash-hackers.org/syntax/quoting) para más. – bschlueter

Respuesta

88

Uso Ctrl + V, Ctrl + M para introducir un carro literal Devuelve el carácter a tu cadena grep. Por lo tanto:

grep -IUr --color "^M" 

funciona - si el ^M hay un CR literal que ha ingresado como sugerí.

Si desea la lista de archivos, también desea agregar la opción -l.

Explicación

  • -I Ignorar archivos binarios
  • -U impide grep para despojar caracteres CR. Por defecto, lo haría si decide que es un archivo de texto.
  • -r lea todos los archivos debajo de cada directorio recursivamente.
+3

Como un hack rápido que funcionaría, pero creo que la solución de lectura humana sería: grep $ '\ r'/bash shell only/grep 'printf '\ r'' – akostadinov

+3

@akostadinov +1, pero los palos de atrás se interpretaron de su comentario;) La segunda opción sería, en otras palabras, ser ** 'grep $ (printf '\ r')' **. Pero para la mayoría de los usos prácticos que implican bash, me quedaría con '$ '\ r''. – jankes

+3

Nota: La opción '-U' solo es relevante para Windows (o cygwin), pero es fundamental. En Windows, el comando no funcionará sin él. – sleske

119

grep probablemente no es la herramienta que desea para esto. Imprimirá una línea para cada línea coincidente en cada archivo. A menos que desee, por ejemplo, ejecutar todos 10 veces en un archivo de 10 líneas, grep no es la mejor manera de hacerlo. Utilización de la búsqueda para ejecutar el archivo de todos los archivos en el árbol y luego grepping través de que por "CRLF" te llevará a una línea de salida para cada archivo que tiene estilo dos finales de línea:

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

le conseguirá algo como:

./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
+0

Ya había descifrado esto, pero gracias de todos modos. 'grep -IUrl --color '^ M'. | xargs -file fromdos 'file'' –

+4

La opción -l de grep le dice que solo enumere los archivos (una vez) en lugar de enumerar las coincidencias en cada archivo. – pjz

+4

No es una buena solución, depender de ese comportamiento (indocumentado, orientado al consumo humano) del programa 'archivo'. Esto es muy frágil Para (solo uno) ejemplo: no funciona con archivos XML, 'archivo' informa' XML document text' independientemente del tipo de líneas nuevas. – leonbloy

14

Si su versión de grep soporta -P (--perl-regexp) opción,

grep -lUP '\r$' 

podrían utilizarse.

6
# 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 
2

La consulta estaba en la ventana ... Tengo un problema similar ... alguien presentó la línea mixta terminaciones en el control de versiones, por lo que ahora tenemos un montón de archivos con 0x0d 0x0d0x0a finales de línea.Tenga en cuenta que

grep -P '\x0d\x0a' 

encuentra todas las líneas, mientras que

grep -P '\x0d\x0d\x0a' 

y

grep -P '\x0d\x0d' 

no encuentra líneas de modo que puede haber algo "más" pasando dentro grep cuando se trata de alinear terminando patrones ... desafortunadamente para mí!

1

Si, como yo, tu minimalista UNIX no incluye detalles como el comando archivo, y las barras invertidas en su grep expresiones simplemente no cooperan, intente esto:

$ 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 

Las modificaciones se puede querer hacer de lo anterior incluyen:

  • ajustar el encuentran de comandos para localizar sólo los archivos que desea analizar
  • cambio de la utilidad volcado comando para desde o lo que sea volcado en un archivo que tiene
  • confirmar que el cortar comando incluye tanto un delantero y trasero espacio, así como hasta la salida carácter hexadecimal del volcado utilidad
  • limitar el volcado salida a los primeros 1000 caracteres o menos para la eficiencia

por ejemplo, algo así como esto puede funcionar para usted, utilizando desde en lugar de volcar :

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

¿Cuál es la función de $ aquí? Funciona, pero ¿cómo? –

+3

http://linux.die.net/Bash-Beginners-Guide/sect_03_03.html –

+6

¡Gracias! Para mayor claridad de los que vienen después, el manual bash dice "Las palabras de la forma $ 'cadena' son tratadas especialmente. La palabra se expande a cadena, con caracteres escapados de barra invertida reemplazados como lo especifica el estándar ANSI C." (Consulte también esta [lista de códigos admitidos] (http://www.gnu.org/software/bash/manual/bashref.html#ANSI_002dC-Quoting)) –

1

puede utilizar el comando archivo en UNIX. Le da la codificación de caracteres del archivo junto con los terminadores de línea.

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