Convertendo em massa "end-of-line" de arquivos de texto entre Windows, GNU/Linux e Mac OS

Publicado por Luís Fernando C. Cavalheiro em 06/11/2013

[ Hits: 13.705 ]

Blog: https://github.com/lcavalheiro/

 


Convertendo em massa "end-of-line" de arquivos de texto entre Windows, GNU/Linux e Mac OS



Camaradinhas, aqui começa mais uma dica do Dino trazendo uns paranauês doidões do tempo em que o amigo Teixeira trabalhava nos ENIACs da vida.

Hoje, quero expandir a utilidade da dica:
Do amigo rcjeferson, trazendo um meio de realizar a dita conversão em massa entre os end-of-line do Windows, GNU/Linux e Mac OS.

Mas antes, vamos à uma conversinha: o que é o end-of-line? Bem, esse é o caractere que o sistema enfia no arquivo no momento em que você pressiona o Enter.

Quando algum outro programa "ler" o arquivo, ele vai encontrar o tal end-of-line e vai entender: "ah, aqui acaba o raio da linha, tenho que passar pra próxima".

Acontece que esses três sistemas operacionais não usam o mesmo end-of-line. O Windows, aferrado ao ASCII e às máquinas de Fax, usa os caracteres <CR> ("carriage return", ou "retorno de carro" - pensem naquele movimento que se precisa fazer ao chegar ao final da linha em uma máquina de escrever. E agora, reimaginem a cena sabendo que o nome daquela peça é carro) e <LF> ("line feed", que é o que abre a nova linha").

O GNU/Linux usa só o <LF>, e o Mac OS usa só o <CR>. Caos total, não é? Ainda mais se você é programador, usa mais de um sistema operacional e fica louquinho quando seu editor de textos estraga tudo.

Mas não se aflija, tudo que você precisa para a tarefa é o Vim. Isso mesmo, o Vim. Na maioria dos casos, isso significa que você não precisa instalar nada no seu computador. E se você não tem o Vim instalado, me dê seu endereço real que eu vou aí te cobrir de socos!

Um exemplo para explicar melhor:

find . -name "*txt" -execdir vi "{}" -c "set ff=dos" -c "wq" \;

Onde:
  • Procura todos os arquivos no diretório atual e subdiretórios dele, cujo nome termina em txt e aplica o comando: vi arquivo -c "set ff=dos" -c "wq" neles.
  • O name "*txt" é só um critério de busca, você pode usar qualquer um que lhe agrade (por exemplo: "-type f" para converter todos os arquivos, "-ctime" pra converter os mais recentes, etc.).
  • O pulo do gato é do -execdir pra frente: -execdir diz para executar o comando a seguir, como se ele fosse executado nativamente do diretório em que o arquivo se encontra. Útil em casos de árvores de diretórios complicadas;
  • "{}" (sim, entre aspas mesmo), serve para dizer ao comando (no caso, o vi) para agir sobre o arquivo localizado pelo find.
  • -c "set ff=dos" (aspas obrigatórias), indica que o vi deve aplicar o comando de modo normal (:set ff=dos) ao arquivo.
  • -c "wq" (aspas obrigatórias), indica que o vi deve aplicar o comando de modo normal (":wq") ao arquivo.

Mas o que fazem esses comandos de modo normal do Vi?

Bem, :set ff=string altera o end-of-line do arquivo, e string pode ser dos (<CR><LF> usado pelo Windows), Unix (<LF> usado pelo GNU/Linux) ou Mac (<CR> usado pelo MacOS).

Já o comando :wq salva e fecha o arquivo. Se o arquivo usar um end-of-line diferente do GNU/Linux, o próprio Vim te indicará isso ao pé da página, quando você abrir o arquivo, conforme você pode ver pelas screenshots a seguir (P.S.: não liguem pros textos, é coisa de RPGista):
Linux: Convertendo em massa end-of-line de arquivos de texto entre Windows, GNU/Linux e Mac OS   Linux: Convertendo em massa end-of-line de arquivos de texto entre Windows, GNU/Linux e Mac OS

Aqui mostra o set ff=mac. O GNU/Linux vai acusar que o arquivo está sem finais de linha (claro, não tem o <LF>). Caso você queira desfazer a caca, reinserindo os finais de linha em um arquivo com end-of-line do Mac OS, será preciso abrir o arquivo pelo Vim e rodar os comandos em modo normal:

:%s/^V^M/^V^M/g
:set ff=unix
:wq


Onde:
  • ^V significa: CTRL V
  • ^M significa: CTRL M

Bem, com esta pequena aula, de que nem sempre instalar um pacote adicional é a melhor saída quando a gambiarra está à disposição, o Dino se despede desejando a todos vocês um bom final de Samhain (o festejo, não o dia, vai do dia 31/10 ao 02/11), um ótimo desaniversário amanhã e uma "quentíssima" amante zumbi!

Outras dicas deste autor

Spotify no OpenSUSE

Oneko: tenha um gato na tela do seu computador

X-Box no Ubuntu 12.04 - Configurando Joystick

Slackware Current: Xorg não subindo após upgrade de 21/08/2015

Imprimindo para PDF a partir de programas rodando sob o Wine no openSUSE 13.2

Leitura recomendada

Acessando compartilhamentos de rede do Windows pelo CentOS

Executando Arquivo de Mídia .opus pelo Terminal

TAR seletivo

Verificando logs do Squid em tempo real

Verificação constante de disponibilidade de serviços

  

Comentários
[1] Comentário enviado por leandro em 07/11/2013 - 20:19h

Como costumo editar arquivos para serem abertos em outros sistemas, sempre tenho que ficar convertendo antes.

Para ajudar, eu monitoro qual é o fim de linha + a codificação do arquivo pela barra de status:

set laststatus=2
set statusline=%f\ %m%r%h%w\ %=\ [TIPO=%Y]\ [COD=%{strlen(&fenc)?&fenc:'none'}/%{&ff}]\ [LN=%L]

E ao salvar um arquivo, eu converto antes a codificação/fim de linha com a função:

function! Encoding(type)
if a:type == "dos"
set fileencoding=iso-8859-1
set fileformat=dos
elseif a:type == "unix"
set fileencoding=utf=8
set fileformat=unix
endif
endfunction


Usando:

:call Encoding("dos")
:call Encoding("unix")

Funciona bem para arquivos únicos. Mas para vários arquivos, a sua solução é a ideal.

Favoritada!

[2] Comentário enviado por rcjeferson em 07/11/2013 - 23:32h

Muito boa sua dica lcavalheiro, sensacional.

Parabens!

[3] Comentário enviado por lcavalheiro em 08/11/2013 - 09:31h


[1] Comentário enviado por leandro em 07/11/2013 - 20:19h:

Como costumo editar arquivos para serem abertos em outros sistemas, sempre tenho que ficar convertendo antes.

Para ajudar, eu monitoro qual é o fim de linha + a codificação do arquivo pela barra de status:

set laststatus=2
set statusline=%f\ %m%r%h%w\ %=\ [TIPO=%Y]\ [COD=%{strlen(&fenc)?&fenc:'none'}/%{&ff}]\ [LN=%L]

E ao salvar um arquivo, eu converto antes a codificação/fim de linha com a função:

function! Encoding(type)
if a:type == "dos"
set fileencoding=iso-8859-1
set fileformat=dos
elseif a:type == "unix"
set fileencoding=utf=8
set fileformat=unix
endif
endfunction


Usando:

:call Encoding("dos")
:call Encoding("unix")

Funciona bem para arquivos únicos. Mas para vários arquivos, a sua solução é a ideal.

Favoritada!


Leandro, dá para usar sua função com esta dica. A linha de comando ficaria:
$ find . -name "*txt" -execdir vi "{}" -c 'call Encoding("dos")' -c "wq" \;

O parâmetro -c na linha de comando diz ao vi que ele tem que usar o argumento do parâmetro como um comando de modo normal, logo ele vai chamar sua função e fazer essa graça toda. Só que como a função usa aspas será preciso limitar o argumento do parâmetro com aspas simples.


[2] Comentário enviado por rcjeferson em 07/11/2013 - 23:32h:

Muito boa sua dica lcavalheiro, sensacional.

Parabens!


Valeu, cara!

[4] Comentário enviado por SuperSlackware em 06/07/2017 - 15:13h

Obrigado Dino, salvou o meu dia essa Hiper, Mega Dica.
Muito Grato



Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts