Caractère '^ M' à la fin des lignes

99

Lorsque j'exécute un script SQL particulier dans des environnements Unix, je vois un caractère «^ M» à la fin de chaque ligne du script SQL lorsqu'il est renvoyé à la ligne de commande. Je ne sais pas sur quel système d'exploitation le script SQL a été créé à l'origine.

Qu'est-ce qui cause ce problème et comment y remédier?

Paul Reiners
la source

Réponses:

79

Cela est dû aux caractères de fin de ligne DOS / Windows. Comme Andy Whitfield l'a dit, la commande Unix dos2unix aidera à résoudre le problème. Si vous souhaitez plus d'informations, vous pouvez lire les pages de manuel de cette commande.

Thomas Owens
la source
3
Sur certains systèmes (par exemple Ubuntu), le nom de cette commande est "fromdos"
bobwienholt
6
Vous pouvez obtenir l'outil sur OSX très facilement brew install dos2unixlorsque vous avez installé homebrew
philipp
73

Corrigez les fins de ligne en viexécutant ce qui suit:

:set fileformat=unix

:w

Tim Abell
la source
2
C'est une réponse brillante. Merci beaucoup. (enregistré en installant dos2unix, un outil que je n'utiliserais probablement qu'une seule fois)
Jamsi
3
cela ne supprime pas le ^Ms pour une raison quelconque. fichier de référence: /etc/timidity/fluidr3_gm.cfg.
phil294
39

La cause est la différence entre la façon dont un système d'exploitation Windows et un système d'exploitation Unix stockent les marqueurs de fin de ligne.

Les systèmes d'exploitation Windows, grâce à leur héritage DOS, stockent une fin de ligne sous forme de paire de caractères - 0x0D0A(retour chariot + saut de ligne). Les systèmes d'exploitation basés sur Unix utilisent simplement 0x0A(un saut de ligne ). Le ^Mque vous voyez est une représentation visuelle de 0x0D(un retour chariot ).

dos2unix vous aidera avec cela. Vous devrez probablement aussi ajuster la source des scripts pour être «compatible Unix».

ColinYounger
la source
Je ne dirais pas que les versions actuelles de Windows ont une sorte d' héritage DOS . Cependant, ils ont toujours des restrictions de compatibilité.
Joey
C'est le moyen le plus simple, c'est de faire un outil de conversion automatique. Merci
Pjl
Mais pourquoi ^M? Pourquoi le «^»? Pourquoi le «M»?
1737973
Parce que c'est un "caractère de contrôle". "^" est la représentation visuelle du clic sur la touche de contrôle. Sous ses octets spécifiques, le ^ est la façon dont l'éditeur les représente.
Hejazzman
24

Le moyen le plus simple est d'utiliser vi. Je sais que cela semble terrible mais c'est simple et déjà installé sur la plupart des environnements UNIX. ^ M est une nouvelle ligne de l'environnement Windows / DOS.

à partir de l'invite de commande: $ vi filename

Appuyez ensuite sur " :" pour accéder au mode commande.

Rechercher et tout remplacer globalement est :%s/^M//g" Appuyez et maintenez la commande puis appuyez sur V puis M " qui remplacera ^ M par rien.

Ensuite, pour écrire et quitter, entrez " :wq" Terminé!

Bernie Perez
la source
Comment le remplacer dans emacs?
herbertD
Merci! VI (M) est génial!
Ionică Bizău
3
Merci pour l'explication sur la façon de taper le caractère ^ M! Je le remplacerais par \ r à la place. Alors j'ai fait:% s / ^ M / \ r / g
aharris88
13

Essayez d'utiliser dos2unix pour retirer le ^ M.

Andy Whitfield
la source
10

Dans vi, faites un :%s/^M//g

Pour ^Mmaintenir la CTRLtouche enfoncée, appuyez sur Vpuis M(Les deux tout en maintenant la touche de contrôle) et le ^Mapparaîtra. Cela trouvera toutes les occurrences et les remplacera par rien.

dogbane
la source
2
Pour remplacer le ^ M par un saut de ligne amical unix::%s/^M/\r/g
Gary Oak
8

Le script SQL a été créé à l'origine sur un système d'exploitation Windows. Les caractères «^ M» sont le résultat du fait que Windows et Unix ont des idées différentes sur ce qu'il faut utiliser pour un caractère de fin de ligne. Vous pouvez utiliser perl sur la ligne de commande pour résoudre ce problème.

perl -pie 's/\r//g' filename.txt
Bill le lézard
la source
Bien sûr, vous POUVEZ utiliser perl, mais suggérez-vous perl plutôt que dos2unix?
Thomas Owens
2
Je propose juste une alternative, puisque quatre personnes ont déjà dit utiliser dos2unix.
Bill the Lizard
2
Oui, j'ai trouvé cela utile parce que je travaille sur un poste de travail rétrograde dans un bureau avec un service informatique préhistorique. Sauf que j'ai utilisé une variante: perl -pi -e "s / \ x0D / \ n / g" file.csv
Rimian
7

Le ^ M est généralement causé par les nouvelles lignes de l'opérateur Windows et traduit sous Unix ressemble à un ^ M. La commande dos2unix devrait bien les supprimer

dos2unix [options] [-c convmode] [-o fichier ...] [-n fichier fichier ...]

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

Sed est encore plus largement disponible et peut faire ce genre de chose aussi si dos2unix n'est pas installé

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

Vous pouvez également essayer tr:

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

Voici les résultats:

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
la source
4

Pour remplacer les caractères ^ M dans l'éditeur vi, utilisez ci-dessous

ouvrez le fichier texte, dites t1.txt

vi t1.txt

Entrez en mode commande en appuyant sur shift + :

puis appuyez sur les touches comme indiqué %s/^M/\r/g

in above ^M is not (shift + 6)M instead it is (ctrl + V)(ctrl + M)
Leela
la source
Votre dernière ligne est ce qui me manquait dans toutes les réponses précédentes. J'ai continué à obtenir `` aucune correspondance trouvée car je faisais shift + 6, alors j'ai fait ce que chaque hacker ferait et contourné mon malentendu avec ma propre solution: enregistrer une macro pour faire $ pour aller à la fin de chaque ligne, puis appuyer sur x, juste répéter la macro pour le nombre de lignes dans le fichier.
darethas
3

Une alternative à la dos2unixcommande consisterait à utiliser des utilitaires standard comme sed.

Par exemple, dos à unix:

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

unix à dos:

sed 's/$/\r/' unix.txt > dos.txt
g4e
la source
1

Vous pouvez supprimer ^ M des fichiers directement via la commande sed, par exemple:

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

Si vous êtes satisfait des modifications, supprimez les fichiers .bak:

rm -v *.bak
Kenorb
la source
0

od -a $file est utile pour explorer ces types de questions sous Linux (similaire à dumphex ci-dessus).

Allan Wind
la source
0

En Perl, si vous ne voulez pas définir la variable $ / et utiliser chomp (), vous pouvez également faire:

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

Mes deux centimes

Ariel Monaco
la source
-1

Une autre commande vi qui fera l'affaire: :%s/.$// Cela supprime le dernier caractère de chaque ligne du fichier. L'inconvénient de cette commande de recherche et de remplacement est qu'elle ne se soucie pas du dernier caractère, alors faites attention de ne pas l'appeler deux fois.

Scottie T
la source
Pourquoi le mentionner si vous savez qu'il n'est pas fiable?
minexew