Convertendo em massa "end-of-line" de arquivos de texto entre Windows, GNU/Linux e Mac OS
Dica publicada em Linux / Comandos
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:
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):
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:
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!
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):
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!
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!