Carácter '^ M' al final de las líneas

99

Cuando ejecuto un script SQL en particular en entornos Unix, veo un carácter '^ M' al final de cada línea del script SQL, ya que se repite en la línea de comandos. No sé en qué sistema operativo se creó originalmente el script SQL.

¿Qué está causando esto y cómo lo soluciono?

Paul Reiners
fuente

Respuestas:

79

Es causado por los caracteres finales de línea de DOS / Windows. Como dijo Andy Whitfield, el comando de Unix dos2unix ayudará a solucionar el problema. Si desea más información, puede leer las páginas de manual de ese comando.

Thomas Owens
fuente
3
En algunos sistemas (es decir, Ubuntu) el nombre de este comando es "fromdos"
bobwienholt
6
Puede obtener la herramienta en OSX muy fácilmente brew install dos2unixcuando tiene instalado Homebrew
philipp
73

Corrija los finales de línea viejecutando lo siguiente:

:set fileformat=unix

:w

Tim Abell
fuente
2
Esta es una respuesta brillante. Muchas gracias. (guardado instalando dos2unix, una herramienta que probablemente solo usaría una vez)
Jamsi
3
esto no elimina la ^Ms por alguna razón. archivo de referencia: /etc/timidity/fluidr3_gm.cfg.
phil294
39

La causa es la diferencia entre cómo un sistema operativo basado en Windows y un sistema operativo basado en Unix almacenan los marcadores de final de línea.

Los sistemas operativos basados ​​en Windows, gracias a su herencia DOS, almacenan un final de línea como un par de caracteres - 0x0D0A(retorno de carro + salto de línea). Los sistemas operativos basados ​​en Unix solo usan 0x0A(un salto de línea ). Lo ^Mque está viendo es una representación visual de 0x0D(un retorno de carro ).

dos2unix le ayudará con esto. Probablemente también necesite ajustar la fuente de los scripts para que sean compatibles con Unix.

ColinYounger
fuente
No diría que las versiones actuales de Windows tienen algún tipo de herencia de DOS . Sin embargo, todavía tienen restricciones de compatibilidad.
Joey
Esta es la forma fácil, si hace una herramienta de conversión automática. Thank's
Pjl
¿Pero por qué ^M? ¿Por qué el '^'? ¿Por qué la 'M'?
1737973
Porque es un "personaje de control". "^" es la representación visual de hacer clic en la tecla de control. Debajo de sus bytes específicos, el ^ es cómo los representa el editor.
Hejazzman
24

La forma más sencilla es utilizar vi. Sé que suena terrible, pero es simple y ya está instalado en la mayoría de los entornos UNIX. El ^ M es una nueva línea del entorno Windows / DOS.

desde el símbolo del sistema: $ vi filename

Luego presione " :" para acceder al modo de comando.

Buscar y reemplazar todo globalmente es :%s/^M//g" Mantenga presionado el control, luego presione V y luego M ", lo que reemplazará ^ M con nada.

Luego, para escribir y salir ingrese " :wq" ¡Listo!

Bernie Pérez
fuente
¿Cómo reemplazarlo en emacs?
herbertD
¡Gracias! ¡VI (M) es genial!
Ionică Bizău
3
¡Gracias por ampliar sobre cómo escribir el carácter ^ M! Lo reemplazaría con \ r en su lugar. Así lo hice:% s / ^ M / \ r / g
aharris88
13

Intente usar dos2unix para quitar el ^ M.

Andy Whitfield
fuente
10

En vi, haz un :%s/^M//g

Para ^Mmantener la CTRLtecla, presione y Vluego M(Ambos mientras mantiene presionada la tecla de control) y ^Maparecerá. Esto encontrará todas las ocurrencias y las reemplazará con nada.

dogbane
fuente
2
Para reemplazar el ^ M con un salto de línea amistoso de Unix::%s/^M/\r/g
Gary Oak
8

El script SQL se creó originalmente en un sistema operativo Windows. Los caracteres '^ M' son el resultado de que Windows y Unix tienen ideas diferentes sobre qué usar para un carácter de final de línea. Puede usar perl en la línea de comandos para solucionar este problema.

perl -pie 's/\r//g' filename.txt
Bill el lagarto
fuente
Claro, PUEDES usar perl, pero ¿sugerirías perl sobre dos2unix?
Thomas Owens
2
Solo estoy brindando una alternativa, ya que cuatro personas ya dijeron que usaran dos2unix.
Bill the Lizard
2
Sí, encontré esto útil porque estoy en una estación de trabajo atrasada trabajando en una oficina con un departamento de TI prehistórico. Excepto que usé una variación: perl -pi -e "s / \ x0D / \ n / g" file.csv
Rimian
7

La ^ M generalmente es causada por las nuevas líneas del operador de Windows, y traducida a Unix parece una ^ M. El comando dos2unix debería eliminarlos muy bien

dos2unix [opciones] [-c modo conv] [-o archivo ...] [-n archivo de salida de archivo ...]

jW.
fuente
5
C:\tmp\text>dos2unix hello.txt helloUNIX.txt

Sed está aún más disponible y puede hacer este tipo de cosas también si dos2unix no está instalado

C:\tmp\text>sed s/\r// hello.txt > helloUNIX.txt  

También puedes probar tr:

cat hello.txt | tr -d \r > helloUNIX2.txt  

Aquí están los resultados:

C:\tmp\text>dumphex hello.txt  
00000000h: 48 61 68 61 0D 0A 68 61 68 61 0D 0A 68 61 68 61 Haha..haha..haha  
00000010h: 0D 0A 0D 0A 68 61 68 61 0D 0A                   ....haha..  

C:\tmp\text>dumphex helloUNIX.txt  
00000000h: 48 61 68 61 0A 68 61 68 61 0A 68 61 68 61 0A 0A Haha.haha.haha..  
00000010h: 68 61 68 61 0A                                  haha.  

C:\tmp\text>dumphex helloUNIX2.txt  
00000000h: 48 61 68 61 0A 68 61 68 61 0A 68 61 68 61 0A 0A Haha.haha.haha..  
00000010h: 68 61 68 61 0A                                  haha.  
Alex Bolotov
fuente
4

Para reemplazar ^ M caracteres en el editor vi, use a continuación

abre el archivo de texto, di t1.txt

vi t1.txt

Ingrese al modo de comando presionando shift + :

luego presione las teclas como se mencionó %s/^M/\r/g

in above ^M is not (shift + 6)M instead it is (ctrl + V)(ctrl + M)
leela
fuente
Tu última línea es lo que me faltaba en todas las respuestas anteriores. Seguí obteniendo 'no se encontraron coincidencias porque estaba haciendo shift + 6, así que hice lo que todos los piratas informáticos harían y eludí mi malentendido con mi propia solución: grabar una macro para hacer $ para ir al final de cada línea y luego presionar x, solo repita la macro para el número de líneas en el archivo.
darethas
3

Una alternativa al dos2unixcomando sería usar utilidades estándar como sed.

Por ejemplo, dos a unix:

sed 's/\r$//' dos.txt > unix.txt

unix para hacer:

sed 's/$/\r/' unix.txt > dos.txt
g4th
fuente
1

Puede eliminar ^ M de los archivos directamente a través del comando sed, por ejemplo:

sed -i'.bak' s/\r//g *.*

Si está satisfecho con los cambios, elimine los archivos .bak:

rm -v *.bak
Kenorb
fuente
0

od -a $file es útil para explorar ese tipo de preguntas en Linux (similar a dumphex en el anterior).

Allan Wind
fuente
0

En Perl, si no desea establecer la variable $ / y usar chomp (), también puede hacer:

$var =~ /\r\n//g;

Mis dos centavos

Ariel Mónaco
fuente
-1

Otro comando vi que servirá: :%s/.$// esto elimina el último carácter de cada línea en el archivo. El inconveniente de este comando de búsqueda y reemplazo es que no le importa cuál sea el último carácter, así que tenga cuidado de no llamarlo dos veces.

Scottie T
fuente
¿Por qué mencionarlo si sabe que no es confiable?
minexew