Carattere '^ M' alla fine delle righe


99

Quando eseguo un particolare script SQL in ambienti Unix, vedo un carattere '^ M' alla fine di ogni riga dello script SQL mentre viene visualizzato nella riga di comando. Non so su quale sistema operativo sia stato originariamente creato lo script SQL.

Cosa sta causando questo problema e come lo risolvo?

Risposte:


79

È causato dai caratteri di fine riga DOS / Windows. Come ha detto Andy Whitfield, il comando Unix dos2unix aiuterà a risolvere il problema. Se vuoi maggiori informazioni, puoi leggere le pagine man per quel comando.


3
Su alcuni sistemi (es. Ubuntu) il nome di questo comando è "fromdos"
bobwienholt

6
Puoi ottenere lo strumento su OSX molto facilmente brew install dos2unixquando hai installato homebrew
philipp

73

Correggi le terminazioni di riga vieseguendo quanto segue:

:set fileformat=unix

:w


2
Questa è una risposta brillante. Grazie molto. (salvato l'installazione di dos2unix, uno strumento che probabilmente
userei

3
questo non rimuove la ^Ms per qualche motivo. file di riferimento: /etc/timidity/fluidr3_gm.cfg.
phil294

39

La causa è la differenza tra il modo in cui un sistema operativo basato su Windows e un sistema operativo basato su Unix memorizzano i marker di fine riga.

I sistemi operativi basati su Windows, grazie alla loro eredità DOS, memorizzano una fine riga come una coppia di caratteri - 0x0D0A(ritorno a capo + avanzamento riga). I sistemi operativi basati su Unix usano solo 0x0A(un avanzamento riga ). Quello ^Mche stai vedendo è una rappresentazione visiva di 0x0D(un ritorno a capo ).

dos2unix ti aiuterà in questo. Probabilmente dovrai anche modificare il sorgente degli script in modo che sia "Unix-friendly".


Non direi che le attuali versioni di Windows abbiano alcun tipo di eredità DOS . Tuttavia, hanno ancora limitazioni di compatibilità.
Joey

Questo è il modo più semplice, è uno strumento di conversione automatica. Ringraziamenti
Pjl

Ma perchè ^M? Perché il '^'? Perché la "M"?
1737973

Perché è un "personaggio di controllo". "^" è la rappresentazione visiva del clic sul tasto Ctrl. Sotto i suoi byte specifici, il ^ è il modo in cui l'editor li rappresenta.
Hejazzman

24

Il modo più semplice è usare vi. So che suona terribile ma è semplice e già installato sulla maggior parte degli ambienti UNIX. ^ M è una nuova riga dall'ambiente Windows / DOS.

dal prompt dei comandi: $ vi filename

Quindi premere " :" per accedere alla modalità di comando.

Cerca e sostituisci tutto a livello globale è :%s/^M//g" Tieni premuto il controllo quindi premi V poi M " che sostituirà ^ M con niente.

Quindi per scrivere e uscire inserisci " :wq" Fatto!


Come sostituirlo in emacs?
herbertD

Grazie! VI (M) è fantastico!
Ionică Bizău

3
Grazie per la spiegazione su come digitare il carattere ^ M! Lo sostituirei invece con \ r. Così ho fatto:% s / ^ M / \ r / g
aharris88


10

In vi, fai a :%s/^M//g

Per ^Mtenere premuto il CTRLtasto, premere Vquindi M(Entrambi mentre si tiene premuto il tasto di controllo) e ^Mapparirà. Questo troverà tutte le occorrenze e le sostituirà con niente.


2
Per sostituire la ^ M con un'interruzione di riga amichevole unix::%s/^M/\r/g
Gary Oak

8

Lo script SQL è stato originariamente creato su un sistema operativo Windows. I caratteri "^ M" sono il risultato di Windows e Unix che hanno idee diverse su cosa usare per un carattere di fine riga. Puoi usare perl dalla riga di comando per risolvere questo problema.

perl -pie 's/\r//g' filename.txt

Certo, PUOI usare perl, ma consiglieresti perl rispetto a dos2unix?
Thomas Owens,

2
Sto solo fornendo un'alternativa, poiché quattro persone hanno già detto di usare dos2unix.
Bill the Lizard,

2
Sì, l'ho trovato utile perché sono su una postazione di lavoro arretrata che lavora in un ufficio con un reparto IT preistorico. Tranne che ho usato una variazione: perl -pi -e "s / \ x0D / \ n / g" file.csv
Rimian

7

La ^ M è tipicamente causata dalle nuove righe dell'operatore Windows e tradotta in Unix appare come una ^ M. Il comando dos2unix dovrebbe rimuoverli bene

dos2unix [opzioni] [-c convmode] [-o file ...] [-n infile outfile ...]


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

Sed è ancora più ampiamente disponibile e può fare questo genere di cose anche se dos2unix non è installato

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

Puoi anche provare tr:

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

Ecco i risultati:

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.  

4

Per sostituire i caratteri ^ M nell'editor vi utilizzare di seguito

apri il file di testo dì t1.txt

vi t1.txt

Entrare in modalità comando premendo shift + :

quindi premere i tasti come indicato %s/^M/\r/g

in above ^M is not (shift + 6)M instead it is (ctrl + V)(ctrl + M)

La tua ultima riga è ciò che mi mancava da tutte le risposte precedenti. Continuavo a ricevere "nessuna corrispondenza trovata bc stavo facendo il turno + 6, quindi ho fatto quello che avrebbe fatto ogni hacker e ho aggirato il mio malinteso con la mia soluzione: registrare una macro da fare $ per andare alla fine di ogni riga e quindi premere x, solo ripetere la macro per il numero di righe nel file.
darethas

3

Un'alternativa al dos2unixcomando sarebbe l'utilizzo di utilità standard come sed.

Ad esempio, dos per unix:

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

unix da fare:

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

1

Puoi rimuovere ^ M dai file direttamente tramite il comando sed, ad esempio:

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

Se sei soddisfatto delle modifiche, rimuovi i file .bak:

rm -v *.bak


0

od -a $file è utile per esplorare questi tipi di domande su Linux (simile a dumphex sopra).


0

In Perl, se non vuoi impostare la variabile $ / e usare chomp () puoi anche fare:

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

I miei due centesimi


-1

Un altro comando vi che farà: :%s/.$// questo rimuove l'ultimo carattere di ogni riga nel file. Lo svantaggio di questo comando di ricerca e sostituzione è che non gli importa quale sia l'ultimo carattere, quindi fai attenzione a non chiamarlo due volte.


Perché menzionarlo se sai che non è affidabile?
minexew
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.