Use pager `less` no arquivo com codificação não padrão

3

Costumo usar o lesspager para visualizar arquivos de log. Normalmente eu uso less -Fpara acompanhar o progresso do log à la tail.

No entanto, alguns arquivos de log usam caracteres nacionais em uma codificação não padrão (latino-1, enquanto o sistema usa UTF-8). Obviamente, eles não serão exibidos corretamente.

Como posso visualizar esses arquivos less?

As únicas soluções que encontrei:

  • Corrija a codificação do arquivo ( recodeou iconv). Isso não funciona enquanto o arquivo ainda está sendo gravado, portanto, não me permite usar less -F. Além disso, destrói o registro de data e hora original dos arquivos de log, o que é ruim do ponto de vista da auditoria.
  • Use um cano ( recode latin1... |less). Funciona para arquivos em andamento, mas infelizmente less -Fnão parece funcionar (ele simplesmente não é atualizado; acredito que o recodeprocesso é encerrado após a conclusão).

Alguma solução que me permita "arrastar" um arquivo de log e ainda mostrar caracteres nacionais corretamente?

sleske
fonte
Parece man lessque existe um pré-processador que você pode definir para corrigir sua codificação.
Isomorphismes
@ isomorphismes: Sim, lesssuporta a chamada de um pré-processador. No entanto, até onde eu sei, o pré-processador lê o arquivo de entrada e cria um novo arquivo para less, portanto, isso não funcionaria less -F.
Sleske

Respostas:

3

Hm, aparentemente lessnão pode fazer isso. A parte no código-fonte menos que implementa o "seguinte" parece ser:

A_F_FOREVER:
                        /*
                         * Forward forever, ignoring EOF.
                         */
                        if (ch_getflags() & CH_HELPFILE)
                                break;
                        cmd_exec();
                        jump_forw();
                        ignore_eoi = 1;
                        while (!sigs)
                        {
                                make_display();
                                forward(1, 0, 0);
                        }
                        ignore_eoi = 0;

Quanto ao meu conhecimento (limitado) de C, isso significa que se "follow" for ativado, menos será:

  1. procurar até o final da entrada
  2. leia e atualize a exibição em um loop, até que Ctrl-C seja pressionado

Se a entrada for um pipel, 1. não retornará até que o tubo sinalize EOF. Se eu usar tail -f xx|less, o tubo nunca sinalizará EOF, portanto menos trava :-(.

No entanto, encontrei uma maneira de conseguir o que quero:

 tail -f inputfile | recode latin1.. > /tmp/tmpfile

então

less +F /tmp/tmpfile

Isso funcionará, porque permite que menos + F funcionem em um arquivo real. Ainda é um pouco estranho, porque recodeaparentemente apenas processa dados em blocos de 4096 bytes, mas funciona ...

sleske
fonte
1

É possível que a recodesaída seja armazenada em buffer no tubo, para que a saída só chegue quando o buffer, provavelmente 4K, estiver cheio. Você pode tentar usar o unbufferscript que acompanha expect.

Dennis Williamson
fonte
Não, esse não é o problema. O recodeprocesso simplesmente sai após detectar EOF para o arquivo (afinal, não há como saber que o arquivo ainda está crescendo); Eu posso confirmar isso usando ps. Então, o buffer não ajuda.
sleske
@lesleske: Você já tentou tail -f | recode ... | less -F?
Dennis Williamson
@ Dennis: Na verdade sim, eu tentei, mas também não ajudou. Parece less -Fsimplesmente não funciona em tubos. Mesmo tail -f myfile | less -Fnão funciona, embora neste caso ambos os processos permaneçam vivos.
sleske
Enfim, +1 para boas dicas. Mesmo se eles não funcionassem, é bom saber isso :-).
sleske
11
@lesleske: A propósito, é less +Fque segue arquivos como tail -f(em vez de less -F). Após alguns testes, parece que recodeestá fazendo um buffer que não pode ser controlado. Isso funciona, mas a saída está em pedaços:tail -f inputfile | recode ... | less +F
Dennis Williamson
0

Leitura sugerida: A seção NATIONAL CHARACTER SETSem

Comando Linux / Unix: menos

harrymc
fonte
que ou 'env LC_ALL = en_US.LATIN1 arquivo menos -F'
akira
Isso não resolve o meu problema. Isso fará com lessque os caracteres latinos-1 sejam aceitos como caracteres regulares (o que significa que não os destaca), mas eles ainda aparecerão incorretamente em um programa de terminal que espera UTF-8 (como esse é o padrão do sistema). Na verdade, quero converter os caracteres Latin-1 em UTF-8 válidos, e não apenas mostrá-los como caracteres de lixo / caixa.
sleske
@lesleske: Não sei como converter e fazer menos ao mesmo tempo em arquivos dinâmicos. Pode-se definir macros por comentário de akira para as várias codificações possíveis que você possui. Isso pressupõe que seu problema seja apenas a exibição e não a conversão pura.
harrymc