Usando 'less' para deixar texto na tela para arquivos pequenos

1

Tenho certeza de ver essa customização do comando menos em algum sistema colega há muito tempo, para imitar 'mais'. O que eu quero:

  • Se o arquivo for curto (menos de uma tela), ele deve se comportar como cat: mostra o conteúdo do arquivo e sai.

  • Se o arquivo tiver mais de uma tela, ele deverá se comportar como de costume, aguardando a entrada do usuário e limpando sua tela ao sair e deixando os comandos anteriores na tela.

Eu tentei experimentar com menos -FX, mas deixa toneladas de coisas na tela para arquivos grandes.

    
por dargaud 06.09.2018 / 14:24

3 respostas

1

Cole isso no seu terminal (ou coloque-o no bashrc):

less_cat(){
     [ "$(wc -l <"$1")" -ge "$LINES" ] && less "$1" || less -FX "$1"
}

Agora você deve poder executar:

less_cat /etc/fstab
less_cat /var/log/messages 

E fará exatamente o que você quer.

NOTA: Esta solução é compatível com BASH / ZSH (veja os comentários)

Boa sorte!

    
por 06.09.2018 / 15:50
2

Não há maneira fácil de contornar isso.

Ou deixe que less use a tela alternativa para deixar o original original ou não (use -X ).

Você não pode esperar que less restaure a tela como estava e comece a usar a tela alternativa depois de ler uma página inteira.

Precisamos de alguma forma esperar até que pelo menos uma página ou e-mail tenha sido lido antes de iniciar less no modo correto e enviar os dados. Algo como:

page_stdin() {
  awk -v l="${LINES:=$(tput lines)}" '
    cmd {print | cmd; next}
    {lines = lines $0 ORS}
    NR == l {cmd = "less"; printf "%s", lines | cmd}
    END {if (!cmd) printf "%s", lines | "less -FX"}'
}
mypager() {
  if [ "$#" -eq 0 ]; then
    page_stdin
  else
    for file do page_stdin < "$file"; done
  fi
}

(com GNU awk , você pode substituir ORS por RT para não adicionar uma nova linha se não estivesse lá).

Mas isso significa que você não começará a ver a saída do comando canalizado em cmd | mypager até que haja uma página inteira no valor dela ou tenha terminado a saída. (tente por exemplo seq 200 | pv -qL40 | mypager comparado a seq 200 | pv -qL40 | less ).

Observe que você não usa itens como LESS=-s e seria enganado por linhas maiores que a tela, a menos que você tenha LESS=-S .

    
por 06.09.2018 / 16:03
1

Se eu entendi corretamente, você gostaria de manter o comportamento de alternância de tela alternativo para arquivos grandes e ativar a opção -X apenas para arquivos pequenos que cabem na tela única e não precisam de rolagem.

Eu não acho que isso seja possível sem escrever um wrapper para "menos". Eu gostaria de ser provado errado, porque eu tive o mesmo problema que você no passado, e eu até tentei modificar o código-fonte "menos" para isso, mas as mudanças necessárias provaram ser bastante invasivas.

Aqui está um pequeno invólucro de exemplo, mas observe que os comandos: n: p (próximo / arquivo anterior) em menos não funcionam - todos os arquivos da linha de comando são concatenados em um único fluxo. Ele também não é capaz de lidar com bytes nulos na entrada, a menos que / usr / bin / awk seja realmente gawk (GNU Awk).

#! /usr/bin/awk -f
BEGIN { "tput lines" | getline max; max -= 2 }
{ l[NR]=$0 }
NR>=max {
        for(i = 1; i <= NR; i++) print l[i] | "less";
        while(getline > 0) print | "less";
}
END { if (NR < max) for(i = 1; i <= NR; i++) print l[i] | "less -FX" }
    
por 06.09.2018 / 16:12