Qual é a maneira mais simples de remover todos os retornos de carro \r
de um arquivo no Unix?
Qual é a maneira mais simples de remover todos os retornos de carro \r
de um arquivo no Unix?
Respostas:
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, dos2unix
não estiver disponível para você, sed
faç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, sed
não estiver disponível, você o ed
fará 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 :-)
\r
só funciona com GNU sed, outra coisa que você pode fazer isso:sed `echo "s/\r//"`
sed
nem echo
reconhecer \r
no MacOS. Nesse caso, apenas printf "\r"
parece funcionar.
sed "s/$(printf '\r')\$//"
$
assim: sed $'s@\r@@g' |od -c
(mas se você poderia substituir com \n
você precisaria para escapar dele)
tr -d '\r' < infile > outfile
Veja tr (1)
tr
não suportar a \r
fuga, tente '\015'
ou talvez um literal '^M'
(em muitos shells em muitos terminais, ctrl-V ctrl-M produzirá um caractere literal de ctrl-M).
outfile = infile
?
someProg <in >out && mv out in
.
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á \r
como escape + r e o reduzirá a uma planície r
e removerá todas as letras minúsculas r
. É por isso que a resposta dada acima em 2009 por Rob não funciona.
E adicionar o /g
modificador garante que mesmo vários \r
sejam removidos, e não apenas o primeiro.
sed -i s/\r// <filename>
ou algo assim; ver man sed
ou 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
.
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.
^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.
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.
Alguém mais recomenda dos2unix
e 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
Se você estiver usando um sistema operacional (como o OS X) que não possui o dos2unix
comando, mas possui um intérprete Python (versão 2.5+), esse comando é equivalente ao dos2unix
comando:
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 ~/.bashrc
na sessão atual), poderá usar o dos2unix
nome na linha de comando da mesma maneira que nos outros exemplos.
É 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
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"
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.
Notepad++
o comando 's Edit / EOL Conversion / Unix (LF)
no seu sistema Windows antes de copiar o arquivo para o seu sistema Linux.
\r
em 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 tcsh
desh
, ainda assim também funcionam no GNU / Linux.
Testado no OS X, OpenBSD e NetBSD no tcsh
Debian GNU / Linux no bash
.
sed
:No tcsh
OS X, o seguinte sed
trecho pode ser usado junto com printf
, como sed
nem echo
manipula \r
da maneira especial como o GNU:
sed `printf 's/\r$//g'` input > output
tr
:Outra opção é tr
:
tr -d '\r' < input > output
sed
e tr
:Parece que tr
preserva a falta de uma nova linha final do arquivo de entrada, enquanto sed
no 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 \r
ou \n
no final do arquivo.
Aqui estão alguns exemplos de testes que podem ser usados para garantir que isso funcione no seu sistema, usando printf
e hexdump -C
; Como alternativa, od -c
també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
%
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)
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
você pode simplesmente fazer isso:
$ echo $(cat input) > output
a * b
...