Comment faire défiler un fichier de données volumineux tout en conservant l'en-tête

19

Supposons que j'ai un grand fichier de données, qui déborde l'écran à la fois verticalement et horizontalement. Comment puis-je parcourir ce fichier, alors que les lignes d'en-tête restent à l'écran?

Pour le moment, j'utilise less -S, afin que je puisse bien faire défiler mon fichier horizontalement et verticalement. Cependant, lors du défilement vers le bas, les lignes d'en-tête disparaissent évidemment. Existe-t-il un moyen de les conserver en utilisant moins?

Une alternative consiste à utiliser vimen mode écran partagé avec :set nowrap. Cependant, maintenant, si je fais défiler horizontalement, la fenêtre supérieure ne défile pas de la même manière ( :windo set scrollbindne fonctionne que pour le défilement vertical pour autant que je sache).

Bernhard
la source
Que voulez-vous dire par en-tête reste visible, tandis que les données continuent de défiler? Voulez-vous dire que vous ne voulez que la première ligne avec les noms de colonne reste la même? S'agit-il d'un seul fichier contenant des données et ces données continuent-elles de changer et vous ne souhaitez donc voir que les lignes modifiées? Voulez-vous uniquement voir les N premières lignes ou les N dernières lignes?
polym
2
@polym: lessou tail -fqui se comportent exactement comme ils le font normalement, sauf que la première ligne affichée à l'écran serait toujours la ligne d'en-tête. Comme les sites Web (ou Excel) avec un en-tête fixe mais un corps défilant.
Mat
@polym ^ quoi qu'il dise!
Debanjan Basu
@polym, pensez à la façon de figer une vue horizontale et verticale dans une feuille de calcul. Les colonnes figées restent en place pendant le défilement.
user208145

Réponses:

11

Si vous connaissez vim, c'est probablement la meilleure option pour vous. Vous pouvez activer horizontal-scroll-bind-only en modifiant 'scrollopt':

set scrollopt=hor

Donc, avec vim -u NONE, vous obtenez le comportement souhaité avec:

:set scrollopt=hor
:set nowrap
:1split
:windo set scrollbind

Vous souhaiterez peut-être ajuster 'sidescroll'et 'sidescrolloff'modifier le nombre de colonnes sautées et la distance à partir de laquelle le saut de bord commence respectivement.

Thor
la source
1
Existe-t-il un moyen de le faire avec moins? Surtout lors du défilement d'énormes fichiers de données (trop volumineux pour être chargés en mémoire)?
NM
@NM: Voir les autres réponses
Thor
J'ai essayé cela et quand je fais défiler la fenêtre du bas, la fenêtre du haut défile aussi
Daniel Serodio
@DanielSerodio: Quelque chose semble avoir changé. Cela fonctionne si vous définissez scrollopt sur hor, voir la réponse mise à jour
Thor
La réponse mise à jour fonctionne comme prévu, merci pour la réponse rapide comme l'éclair :)
Daniel Serodio
17

Sur les terminaux prenant en charge la définition de la région de défilement:

tailf() ( # args: <file> [<number-of-header-lines>]
  trap 'tput csr 0 "$((LINES-1))"' INT
  tput csr "$((1+${2-1}))" "$((LINES-1))"
  tput clear
  {
    head -n"${2-1}"
    printf "%${COLUMNS}s\n" "" | tr ' ' =
    tail -n "$((LINES-1-${2-1}))" -f
  } < "$1"
)

(suppose un shell comme zshou bashqui définit les variables $COLUMNSet en $LINESfonction de la taille du terminal).

Stéphane Chazelas
la source
1
Mec! C'est pieux! Désolé, je ne pouvais pas me contrôler. Pourriez-vous me diriger vers des pages Web ou des commandes ou des variables pour implémenter les fonctions suivantes?
Debanjan Basu
1. sortir avec q 2. faire défiler vers le bas avec les touches upetdown
Debanjan Basu
est-il possible de se superposer lesssans utiliser headet tailde redessiner l'écran à chaque fois? J'ai toujours <3 votre solution btw. Je ne le marque pas encore correctement parce que vous semblez le modifier et je ne veux pas que vous soyez complaisant; la complaisance est un tueur de créativité, me dit-on! :)
Debanjan Basu
@DebanjanBasu vous pouvez utiliser less -Xà la place de tail -n ...ci - dessus mais la touche "up" supprime l'en-tête là-bas.
Stéphane Chazelas
Comme je l'ai dit, si vous avez de meilleures idées, dirigez-moi vers cela, ou mieux encore, veuillez peaufiner votre réponse davantage. J'ai dû le marquer comme correct parce que vous avez répondu à la question que j'ai posée initialement. L'idée est d'avoir un lessenvironnement pris en sandwich entre un en-tête et un pied de page, pour en faire un outil plus général.
Debanjan Basu
6

Essayez ceci (vous devrez installer multitail):

multitail -du -t "$(head -n 1 filename)" filename

ou, pour les en-têtes de plus d'une ligne:

multitail -wh 2 -l "head -n 2 filename" filename

Si vous souhaitez suivre la sortie de la commande au lieu d'un fichier:

multitail -wh 2 -l "command | head -n 2" -l command

ou utiliser -tselon le cas. Notez que vous devrez peut-être utiliser unbufferpour que la sortie de votre commande apparaisse immédiatement.

Vous pouvez utiliser -Dpour désactiver l'affichage des lignes d'état pour les -whformulaires (cela irait à l'encontre de l'objectif du -tformulaire).

En pause jusqu'à nouvel ordre.
la source
2

La réponse de Thor n'a pas mentionné la désactivation du "scrollopt" vertical, ce qui fait défiler les deux fenêtres verticalement. Donc pour moi, la solution complète est de coller ceci dans vim:

:set scrollopt+=hor
:set scrollopt-=ver
:set nowrap
:1split
:windo set scrollbind
tomasz
la source
Vous pouvez définir scrolloptdirectement avec :scrollopt=horou :scrollopt=hor,jump, selon vos préférences. Voici le VimDoc pour scrollopt.
Michael
1

Voici ce que j'ai obtenu avec tmux:

#!/bin/bash

tmux new-session -s main -n 'w1' -d
tmux send-keys -t main:w1.0 "tail -f <(head -n1 $1)" C-j
tmux split-window -v
tmux resize-pane -t 0 -y 2
tmux send-keys -t 1 "tail -n+2 $1|less -S" C-j
tmux attach -t main

C'est une extension de la réponse de user80519 pour le tmuxfractionnement de fenêtres. Enregistrez sous hless.sh, rendez-le exécutable et utilisez-le comme

hless.sh file
Saddy
la source