Caractere '^ M' no final das linhas

99

Quando executo um script SQL específico em ambientes Unix, vejo um caractere '^ M' no final de cada linha do script SQL, conforme ele é ecoado na linha de comando. Não sei em qual sistema operacional o script SQL foi criado originalmente.

O que está causando isso e como faço para corrigir isso?

Paul Reiners
fonte

Respostas:

79

É causado pelos caracteres de finalização de linha do DOS / Windows. Como Andy Whitfield disse, o comando Unix dos2unix ajudará a resolver o problema. Se você quiser mais informações, pode ler as páginas de manual desse comando.

Thomas Owens
fonte
3
Em alguns sistemas (por exemplo, Ubuntu), o nome deste comando é "fromdos"
bobwienholt
6
Você pode obter a ferramenta no OSX muito facilmente com brew install dos2unixo homebrew instalado
philipp
73

Corrija os finais de linha viexecutando o seguinte:

:set fileformat=unix

:w

Tim Abell
fonte
2
Esta é uma resposta brilhante. Muito Obrigado. (salvo ao instalar dos2unix, uma ferramenta que provavelmente só usaria uma vez)
Jamsi
3
isso não remove os ^Ms por algum motivo. arquivo de referência: /etc/timidity/fluidr3_gm.cfg.
phil294
39

A causa é a diferença entre como um sistema operacional baseado em Windows e um sistema operacional baseado em Unix armazenam os marcadores de fim de linha.

Os sistemas operacionais baseados em Windows, graças à sua herança DOS, armazenam um fim de linha como um par de caracteres - 0x0D0A(retorno de carro + alimentação de linha). Sistemas operacionais baseados em Unix apenas usam 0x0A(um feed de linha ). O que ^Mvocê está vendo é uma representação visual de 0x0D(um retorno de carro ).

dos2unix vai ajudar com isso. Você provavelmente também precisa ajustar a fonte dos scripts para ser 'amigável ao Unix'.

ColinYounger
fonte
Eu não diria que as versões atuais do Windows têm qualquer tipo de herança DOS . Eles ainda têm restrições de compatibilidade, no entanto.
Joey
Esta é a maneira mais fácil, você faz uma ferramenta de conversão automática. Obrigado
Pjl
Mas porque ^M? Por que o '^'? Por que o 'M'?
1737973
Porque é um "personagem de controle". "^" é a representação visual de clicar na tecla de controle. Abaixo de seus bytes específicos, o ^ é como o editor os representa.
Hejazzman
24

A maneira mais fácil é usar vi. Eu sei que parece terrível, mas é simples e já está instalado na maioria dos ambientes UNIX. O ^ M é uma nova linha do ambiente Windows / DOS.

no prompt de comando: $ vi filename

Em seguida, pressione " :" para entrar no modo de comando.

Pesquisar e substituir tudo globalmente é :%s/^M//g" Pressione e segure o controle, pressione V e, em seguida, M " que substituirá ^ M por nada.

Então, para escrever e sair, digite " :wq" Feito!

Bernie Perez
fonte
Como substituí-lo no emacs?
herbertD
Obrigado! VI (M) é ótimo!
Ionică Bizău
3
Obrigado pela expansão sobre como digitar o caractere ^ M! Em vez disso, eu o substituiria por \ r. Então eu fiz:% s / ^ M / \ r / g
aharris88
13

Tente usar o dos2unix para retirar o ^ M.

Andy Whitfield
fonte
10

No vi, faça um :%s/^M//g

Para obter o ^Mporão da CTRLtecla, pressione Ventão M(ambos enquanto segura a tecla Control) eo ^Maparecerá. Isso localizará todas as ocorrências e as substituirá por nada.

dogbane
fonte
2
Para substituir o ^ M por uma quebra de linha amigável do Unix::%s/^M/\r/g
Gary Oak
8

O script SQL foi originalmente criado em um sistema operacional Windows. Os caracteres '^ M' são o resultado do Windows e do Unix terem idéias diferentes sobre o que usar para um caractere de fim de linha. Você pode usar perl na linha de comando para corrigir isso.

perl -pie 's/\r//g' filename.txt
Bill the Lizard
fonte
Claro, você PODE usar perl, mas você sugeriria perl em vez de dos2unix?
Thomas Owens,
2
Estou apenas apresentando uma alternativa, visto que quatro pessoas já disseram para usar dos2unix.
Bill the Lizard,
2
Sim, achei isso útil porque estou em uma estação de trabalho retrógrada, trabalhando em um escritório com um departamento de TI pré-histórico. Exceto que usei uma variação: perl -pi -e "s / \ x0D / \ n / g" file.csv
Rimian
7

O ^ M é normalmente causado pelas novas linhas do operador do Windows e traduzido para o Unix parece um ^ M. O comando dos2unix deve removê-los bem

dos2unix [opções] [-c convmode] [-o arquivo ...] [-n arquivo de saída infile ...]

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

O Sed está ainda mais disponível e pode fazer esse tipo de coisa também se o dos2unix não estiver instalado

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

Você também pode tentar tr:

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

Aqui estão os 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
fonte
4

Para substituir os caracteres ^ M no editor vi, use abaixo

abra o arquivo de texto, diga t1.txt

vi t1.txt

Entre no modo de comando pressionando shift + :

em seguida, pressione as teclas conforme mencionado %s/^M/\r/g

in above ^M is not (shift + 6)M instead it is (ctrl + V)(ctrl + M)
leela
fonte
Sua última linha é o que estava faltando em todas as respostas anteriores. Continuei recebendo 'nenhuma correspondência encontrada bc estava fazendo shift + 6, então fiz o que todo hacker faria e contornei meu mal-entendido com minha própria solução: grave uma macro para fazer $ para ir ao final de cada linha e pressione x, apenas repetir a macro para o número de linhas no arquivo.
darethas
3

Uma alternativa ao dos2unixcomando seria usar utilitários padrão como sed.

Por exemplo, dos para unix:

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

unix para fazer:

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

Você pode remover ^ M dos arquivos diretamente por meio do comando sed, por exemplo:

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

Se você estiver satisfeito com as mudanças, remova os arquivos .bak:

rm -v *.bak
Kenorb
fonte
0

od -a $file é útil para explorar esses tipos de pergunta no Linux (semelhante ao dumphex acima).

Allan Wind
fonte
0

Em Perl, se você não quiser definir a variável $ / e usar chomp (), você também pode fazer:

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

Meus dois centavos

Ariel Monaco
fonte
-1

Outro comando vi que fará: :%s/.$// Isso remove o último caractere de cada linha no arquivo. A desvantagem desse comando de pesquisa e substituição é que ele não se importa com o último caractere, portanto, tome cuidado para não chamá-lo duas vezes.

Scottie T
fonte
Por que mencioná-lo se você sabe que não é confiável?
minexew