it-swarm.dev

Alterar codificação de arquivo para utf-8 via vim em um script

acabei de ser derrubado depois que nosso servidor foi atualizado do Debian 4 para 5. Nós mudamos para o ambiente UTF-8 e agora temos problemas em fazer com que o texto seja impresso corretamente no navegador, porque todos os arquivos estão em não-arquivos. codificações utf8 como iso-8859-1, ascii, etc.

Eu tentei muitos scripts diferentes.

O primeiro que eu tentei é "iconv". Aquele não funciona, ele altera o conteúdo, mas o enconding de arquivos ainda é não-utf8.

O mesmo problema com o encaixe, o encamv, o convmv e algumas outras ferramentas que eu instalei através do apt-get.

Então eu encontrei um código python, que usa chardet módulo Universal Detector, para detectar a codificação de um arquivo (que funciona bem), mas usando a classe unicode ou a classe codec para salvá-lo como utf-8 não funciona, sem erros.

A única maneira que encontrei para obter o arquivo e seu conteúdo convertido em UTF-8 é o vi.

Estas são as etapas que faço para um arquivo:

vi filename.php
:set bomb
:set fileencoding=utf-8
:wq

É isso aí. Aquele funciona perfeito. Mas como posso fazer isso rodar através de um script. Eu gostaria de escrever um script (linux Shell) que atravesse um diretório pegando todos os arquivos php, depois convertendo-os usando vi com os comandos acima. Como eu preciso para iniciar o aplicativo vi, eu não sei como fazer algo assim:

"vi --run-command=':set bomb, :set fileencoding=utf-8' filename.php"

Espero que alguém possa me ajudar.

50
NovumCoder

Essa é a maneira mais simples de fazer isso facilmente na linha de comando:

vim +"argdo se bomb | se fileencoding=utf-8 | w" $(find . -type f -name *.php)

Ou melhor ainda, se o número de arquivos for muito grande:

find . -type f -name *.php | xargs vim +"argdo se bomb | se fileencoding=utf-8 | w"
23
John Weldon

Você poderia colocar seus comandos em um arquivo, vamos chamá-lo script.vim:

set bomb
set fileencoding=utf-8
wq

Então você invoca o Vim com a opção -S (source) para executar o script no arquivo que você deseja corrigir. Para fazer isso em um monte de arquivos que você poderia fazer

find . -type f -name "*.php" -exec vim -S script.vim {} \;

Você também pode colocar os comandos do Vim na linha de comando usando a opção +, mas acho que pode ser mais legível assim.

Nota: Eu não testei isso.

16
Hans W

Você pode realmente querer set nobomb (BOM = byte order mark), especialmente no mundo [not windows].

por exemplo, eu tinha um script que não funcionava porque havia uma marca de ordem de byte no início. Normalmente não é exibido em editores (mesmo com setlist no vi), ou no console, então é difícil de detectar.

O arquivo ficou assim

#!/usr/bin/Perl
...

Mas tentando executá-lo, recebo

./filename
./filename: line 1: #!/usr/bin/Perl: No such file or directory

Não exibido, mas no início do arquivo, é a BOM de 3 bytes. Então, no que diz respeito ao linux, o arquivo não começa com #!

A solução é

vi filename
:set nobomb
:set fileencoding=utf-8
:wq

Isso remove a lista de materiais no início do arquivo, tornando-a correta utf8. 

O NB Windows usa a BOM para identificar um arquivo de texto como utf8, em vez de ANSI. Linux (e a especificação oficial) não.

3
Andrew Murphy

A resposta aceita manterá o último arquivo aberto no Vim. Este problema pode ser facilmente resolvido usando a opção -c do Vim,

vim +"argdo set bomb | set fileencoding=utf-8 | w" -c ":q" file1.txt file2.txt

Se você precisar apenas processar um arquivo, o seguinte também funcionará, 

vim -c ':set bomb' -c ':set fileencoding=utf-8' -c ':wq' file1.txt
0
Libin Wen