Remover retorno de carro no Unix

Respostas:

261

Eu estou indo supor que você retornos de carro médios ( CR, "\r", 0x0d) nas extremidades das linhas, em vez de apenas cega dentro de um arquivo (você pode tê-los no meio de cordas pelo que sei). Usando este arquivo de teste com a apenas CRno final da primeira linha:

$ cat infile
hello
goodbye

$ cat infile | od -c
0000000   h   e   l   l   o  \r  \n   g   o   o   d   b   y   e  \n
0000017

dos2unix é o caminho a percorrer se estiver instalado no seu sistema:

$ cat infile | dos2unix -U | od -c
0000000   h   e   l   l   o  \n   g   o   o   d   b   y   e  \n
0000016

Se, por algum motivo, dos2unixnão estiver disponível para você, sedfaça-o:

$ cat infile | sed 's/\r$//' | od -c
0000000   h   e   l   l   o  \n   g   o   o   d   b   y   e  \n
0000016

Se, por algum motivo, sednão estiver disponível, você o edfará de maneira complicada:

$ echo ',s/\r\n/\n/
> w !cat
> Q' | ed infile 2>/dev/null | od -c
0000000   h   e   l   l   o  \n   g   o   o   d   b   y   e  \n
0000016

Se você não tiver nenhuma dessas ferramentas instaladas na sua caixa, terá problemas maiores do que tentar converter arquivos :-)

paxdiablo
fonte
13
\rsó funciona com GNU sed, outra coisa que você pode fazer isso:sed `echo "s/\r//"`
Lapo
15
Nem sednem echoreconhecer \rno MacOS. Nesse caso, apenas printf "\r"parece funcionar.
21440 Steve
30
Para elaborar o comentário de @ steve: Em um Mac, use o seguinte: sed "s/$(printf '\r')\$//"
mklement0
7
Para emitir correção no mac você também pode prefixar o aspa simples sed string com $assim: sed $'s@\r@@g' |od -c (mas se você poderia substituir com \nvocê precisaria para escapar dele)
nhed
1
Não tenho 100% de certeza, mas para o OS X, usar CTRL-V + CTRL-Mno lugar de \raparência pode funcionar.
240
tr -d '\r' < infile > outfile

Veja tr (1)

Henrik Gustafsson
fonte
4
Não é bom: 1. não funciona no local, 2. pode substituir \ r também não na EOL (que pode ou não ser o que você deseja ...).
Tomasz Gandor
10
1. A maioria das ferramentas unixy funciona dessa maneira, e geralmente é a maneira mais segura de fazer as coisas, pois se você errar, ainda tem o original. 2. A questão, conforme declarada, é remover retornos de carro, não converter finais de linha. Mas existem muitas outras respostas que podem atendê-lo melhor.
Henrik Gustafsson
1
Se o seu trnão suportar a \rfuga, tente '\015'ou talvez um literal '^M'(em muitos shells em muitos terminais, ctrl-V ctrl-M produzirá um caractere literal de ctrl-M).
tripleee
Então, como alguém muda quando você quer outfile = infile?
20917 Christopher
3
@donlan, resposta tardia, mas você costuma usar algo como: someProg <in >out && mv out in.
paxdiablo
38

Moda antiga:

tr -d '\r' < filewithcarriagereturns > filewithoutcarriagereturns
plinto
fonte
32

A maneira mais simples no Linux é, na minha humilde opinião,

sed -i 's/\r$//g' <filename>

As aspas fortes em torno do operador de substituição 's/\r//'são essenciais . Sem eles, o shell interpretará \rcomo escape + r e o reduzirá a uma planície re removerá todas as letras minúsculas r. É por isso que a resposta dada acima em 2009 por Rob não funciona.

E adicionar o /gmodificador garante que mesmo vários \rsejam removidos, e não apenas o primeiro.

wfjm
fonte
27

Existe um utilitário chamado dos2unix que existe em muitos sistemas e pode ser facilmente instalado na maioria.

Emil H
fonte
6
Às vezes, também é chamado fromdos (e todos).
Anônimo
Link é agora para baixo, por favor visite http://dos2unix.sourceforge.net/ vez
RyanQuey
7

sed -i s/\r// <filename>ou algo assim; ver man sedou a riqueza de informações disponíveis na web sobre o uso de sed.

Uma coisa a salientar é o significado preciso de "retorno de carro" acima; se você realmente quer dizer o caractere de controle único "retorno de carro", o padrão acima está correto. Se você quis dizer, de maneira geral, CRLF (retorno de carro e um avanço de linha, que é como os feeds de linha são implementados no Windows), provavelmente você deseja substituir \r\n. Os feeds de linha simples (nova linha) no Linux / Unix são \n.

Roubar
fonte
Estou tentando usar -> sed 's / \ r \ n / = /' countryNew.txt> demo.txt que não funciona. "tigre" "leão".
Suvasis 13/09/13
devemos considerar isso como um mac? Tenho notado Darwin sed parece ter diferentes comandos e conjuntos de recursos por padrão que a maioria das versões do Linux ...
jsh
4
Para sua informação, s/\r//não parece remover retornos de carro no OS X, mas sim remover rcaracteres literais . Ainda não sei por que isso acontece. Talvez tenha algo a ver com a maneira como a string é citada? Como solução alternativa, usar CTRL-V + CTRL-Mno lugar de \rparece funcionar.
6

Se você é um usuário do Vi, pode abrir o arquivo e remover o retorno de carro com:

:%s/\r//g

ou com

:1,$ s/^M//

Observe que você deve digitar ^ M pressionando ctrl-v e, em seguida, ctrl-m.

Alex Giotis
fonte
2
Não é ótimo: se o arquivo tiver CR em todas as linhas (isto é, um arquivo DOS correto), o vim o carregará com filetype = dos, e não exibirá ^M-s. Para contornar isso, há uma tonelada de pressionamentos de tecla, que não é para isso que o vim é feito;). Eu apenas iria sed -i, e depois `-e 's / \ r $ // g' para limitar a remoção aos CRs na EOL.
Tomasz Gandor
6

Mais uma vez uma solução ... Porque sempre há mais uma:

perl -i -pe 's/\r//' filename

É legal porque está no lugar e funciona em todos os tipos de unix / linux com os quais trabalhei.

Allan Cano
fonte
3

Alguém mais recomenda dos2unixe eu recomendo fortemente também. Estou apenas fornecendo mais detalhes.

Se instalado, pule para a próxima etapa. Se ainda não estiver instalado, eu recomendaria instalá-lo via yum:

yum install dos2unix

Então você pode usá-lo como:

dos2unix fileIWantToRemoveWindowsReturnsFrom.txt
James Oravec
fonte
2

Se você estiver usando um sistema operacional (como o OS X) que não possui o dos2unixcomando, mas possui um intérprete Python (versão 2.5+), esse comando é equivalente ao dos2unixcomando:

python -c "import sys; import fileinput; sys.stdout.writelines(line.replace('\r', '\n') for line in fileinput.input(mode='rU'))"

Isso lida com os arquivos nomeados na linha de comando, bem como com os pipes e redirecionamentos, assim como dos2unix. Se você adicionar esta linha ao seu arquivo ~ / .bashrc (ou arquivo de perfil equivalente para outros shells):

alias dos2unix="python -c \"import sys; import fileinput; sys.stdout.writelines(line.replace('\r', '\n') for line in fileinput.input(mode='rU'))\""

... na próxima vez que você fizer login (ou executar source ~/.bashrcna sessão atual), poderá usar o dos2unixnome na linha de comando da mesma maneira que nos outros exemplos.

Chris Johnson
fonte
2

É o seguinte,

%0dé o caractere de retorno de carro. Para torná-lo compilável com o Unix. Precisamos usar o comando abaixo.

dos2unix fileName.extension fileName.extension

Sireesh Yarlagadda
fonte
1

tente fazer isso para converter o arquivo dos em arquivo unix:

arquivo fromdos

Hawston
fonte
1

Para UNIX ... notei que os cabeçalhos Unicode removidos dos2unix formam meu arquivo UTF-8. No git bash (Windows), o script a seguir parece funcionar bem. Ele usa sed. Observe que ele remove apenas retornos de carro no final das linhas e preserva os cabeçalhos Unicode.

#!/bin/bash

inOutFile="$1"
backupFile="${inOutFile}~"
mv --verbose "$inOutFile" "$backupFile"
sed -e 's/\015$//g' <"$backupFile" >"$inOutFile"
LexieHankins
fonte
1

Se você estiver executando um ambiente X e tiver um editor adequado (código do visual studio), seguiria a recomendação:

Código do Visual Studio: Como mostrar finais de linha

Basta ir ao canto inferior direito da tela, o código do visual studio mostrará a codificação do arquivo e a convenção de fim de linha seguida pelo arquivo. Com um simples clique, você poderá alternar.

Basta usar o código visual como substituto do bloco de notas ++ em um ambiente linux e você estará pronto.

99Sono
fonte
Ou use Notepad++o comando 's Edit / EOL Conversion / Unix (LF)no seu sistema Windows antes de copiar o arquivo para o seu sistema Linux.
Jesse Chisholm
1

Removendo \rem qualquer sistema UNIX®:

A maioria das soluções existentes nesta pergunta é específica do GNU e não funcionaria no OS X ou BSD; as soluções abaixo deve funcionar em muitos outros sistemas UNIX, e em qualquer shell, a partir tcshdesh , ainda assim também funcionam no GNU / Linux.

Testado no OS X, OpenBSD e NetBSD no tcshDebian GNU / Linux no bash.


Com sed:

No tcshOS X, o seguinte sedtrecho pode ser usado junto com printf, como sednem echomanipula \rda maneira especial como o GNU:

sed `printf 's/\r$//g'` input > output

Com tr:

Outra opção é tr:

tr -d '\r' < input > output

Diferença entre sede tr:

Parece que trpreserva a falta de uma nova linha final do arquivo de entrada, enquanto sedno OS X e NetBSD (mas não no OpenBSD ou GNU / Linux) insere uma nova linha final no final do arquivo, mesmo se houver alguma falta na entrada. à direita \rou \nno final do arquivo.


Teste:

Aqui estão alguns exemplos de testes que podem ser usados ​​para garantir que isso funcione no seu sistema, usando printfe hexdump -C; Como alternativa, od -ctambém pode ser usado se seu sistema estiver ausente hexdump:

% printf 'a\r\nb\r\nc' | hexdump -C
00000000  61 0d 0a 62 0d 0a 63                              |a..b..c|
00000007
% printf 'a\r\nb\r\nc' | ( sed `printf 's/\r$//g'` /dev/stdin > /dev/stdout ) | hexdump -C
00000000  61 0a 62 0a 63 0a                                 |a.b.c.|
00000006
% printf 'a\r\nb\r\nc' | ( tr -d '\r' < /dev/stdin > /dev/stdout ) | hexdump -C
00000000  61 0a 62 0a 63                                    |a.b.c|
00000005
% 
cnst
fonte
0

Eu usei python para isso, aqui meu código;

end1='/home/.../file1.txt'
end2='/home/.../file2.txt'
with open(end1, "rb") as inf:
     with open(end2, "w") as fixed:
        for line in inf:
            line = line.replace("\n", "")
            line = line.replace("\r", "")
            fixed.write(line)
Rafael
fonte
0

Embora seja um post antigo, recentemente me deparei com o mesmo problema. Como eu tinha todos os arquivos para renomear dentro de / tmp / blah_dir /, já que cada arquivo neste diretório tinha "/ r" caractere à direita (mostrando "?" No final do arquivo), então fazê-lo de maneira de script era apenas o que eu conseguia pensar.

Eu queria salvar o arquivo final com o mesmo nome (sem deixar nenhum caractere). Com sed, o problema era o nome do arquivo de saída que eu precisava mencionar outra coisa (que eu não queria).

Tentei outras opções, conforme sugerido aqui (não considerado dos2unix devido a algumas limitações), mas não funcionou.

Eu tentei com "awk" finalmente, que funcionava onde eu usava "\ r" como delimitador e fiz a primeira parte :

truque é:

echo ${filename}|awk -F"\r" '{print $1}'

Abaixo do snippet de script que usei (onde todos os arquivos tinham "\ r" como caractere à direita no caminho / tmp / blah_dir /) para corrigir meu problema:

cd /tmp/blah_dir/
for i in `ls`
  do
    mv   $i     $(echo $i | awk -F"\r" '{print $1}')
done

Nota: Este exemplo não é muito exato, porém próximo ao que eu trabalhei (mencionando aqui apenas para ter uma idéia melhor do que eu fiz)

Ashish K Srivastava
fonte
0

Eu fiz esse shell-script para remover o caractere \ r. Funciona em solaris e red hat:

#!/bin/ksh

LOCALPATH=/Any_PATH

for File in `ls ${LOCALPATH}`
do
   ARCACT=${LOCALPATH}/${File}
   od -bc ${ARCACT}|sed -n 'p;n'|sed 's/015/012/g'|awk '{$1=""; print $0}'|sed 's/ /\\/g'|awk '{printf $0;}'>${ARCACT}.TMP
   printf "`cat ${ARCACT}.TMP`"|sed '/^$/d'>${ARCACT}
   rm ${ARCACT}.TMP
done

exit 0
Heloderma Suspectum
fonte
-1

você pode simplesmente fazer isso:

$ echo $(cat input) > output
mma7
fonte
Não sei por que alguém deu '-1'. Esta é uma resposta perfeitamente boa (e a única que funcionou para mim).
FractalSpace
1
Oh, desculpe, fui eu. Espere, olhe, ele realmente não funciona para '\ r'!
Viacheslav Rodionov
1
@FractalSpace Esta é uma péssima ideia! Ele destrói completamente todo o espaçamento no arquivo e deixa todo o conteúdo do arquivo sujeito a interpretação pelo shell. Experimentá-lo com um arquivo que contém uma linha a * b...
Tom Fenech