pipe l'output di un comando in meno o in relazione alla durata del gatto
Domanda
Per prima cosa, lasciatemi dire che questo è un di programmazione domanda (e quindi non appartiene a superutente et. Al. ) perché sto parlando programmazione della shell. Questo potrebbe quasi essere una domanda di golf, ma non ho una risposta per cominciare, in modo che qualsiasi aiuto sarebbe apprezzato: -)
Quindi, la storia è: mi piace roba tubo nel less
con l'opzione --quit-if-one-screen
perché è molto confortevole: less
does non si ottiene a modo mio, quando non necessaria. O lo fa? Quando il mio prompt è già in fondo alla mia finestra di terminale, questa opzione fa esattamente quello che voglio (vale a dire less
si comporta come cat
). Ma, quando la mia richiesta corrente è alla parte superiore della finestra, less
prima stampe un sacco di righe vuote a trasparente dello schermo, quindi stampa il mio file (breve) nella parte inferiore dello schermo, e solo allora si rende conto che c'è meno il testo di una schermata, così esce e ottengo il mio prompt di schiena.
Ma questo comportamento non è grande, perché di tutte quelle inutili righe vuote. Ho provato diverse opzioni, o scritto gli script e gli alias, e il meglio che potevo venire con sarebbe questo (sto usando zsh, in modo che la Shell è già in grado di duplicare tubi e così via):
function catless() {
cat \
>>( bucket -$LINES | cat ) \
>>( bucket +$LINES | less )
}
Dove bucket
è un altro script che ho appena scritto, che copia stdin per stdout se si tratta di meno di N righe (con -N) o più di n (con + N).
Ho postato qui: http: // Questo esempio vi .net / Gyom / copia-stdin-to-stdout-o-non-seconda-on-length
E ls | catless
quasi fabbrica. Ma, per ragioni di sincronizzazione, i diversi processi coinvolti qui non ottengono l'accesso al terminale in modo corretto e tutto viene eseguito in background (in particolare, non ho mai ottenere una corretta less
qui, e la richiesta ritorna troppo presto). Ma forse ho preso la strada sbagliata.
Quindi, per riassumere, quello che voglio è tale una funzione / script / qualunque cosa che posso digitare ls | catless
e si comporta esattamente come ls | cat
quando l'uscita del ls
è più breve di uno schermo, e come ls | less
quando più.
Tutte le idee?
Soluzione
notizia per i meno la versione 406 , vedo “Don' t mossa verso il basso dello schermo del prima pagina.”. Quale versione avete? La mia versione del sistema è 382 e si muove verso il basso dello schermo prima della stampa (causando righe vuote se c'è solo una schermata e -F
viene utilizzato).
Ho appena installato la versione 436, e sembra di fare ciò che si vuole quando somministrato -FX
(metterlo nella LESS
env var con le altre preferenze per lasciare qualcosa di utilizzare tali preferenze da solo in esecuzione less
).
Se non è possibile ottenere la nuova versione, si potrebbe provare questo, invece:
function catless() {
local line buffer='' num=0 limit=$LINES
while IFS='' read -r line; do
buffer="$buffer$line"$'\n'
line=''
num=$(( num+1 ))
[[ $num -ge $limit ]] && break
done
if [[ $num -ge $limit ]]; then
{ printf %s "$buffer$line"; cat } | less
else
printf %s "$buffer$line"
fi
}
La chiave è che il guscio deve sapere se il ci sono più righe nel file rispetto allo schermo prima che (potenzialmente) lancia less
(la tecnica multi-io inizialmente usato può essere eseguito solo cose nei precedenti). Se il read
in guscio non è abbastanza robusto per voi, è possibile sostituirlo con rielaborazione del codice un po ':
function cat_up_to_N_lines_and_exit_success_if_more() {
# replace this with some other implmentation
# if read -r is not robust enough
local line buffer='' num=0 limit="$1"
while IFS='' read -r line; do
buffer="$buffer$line"$'\n'
line=''
num=$(( num+1 ))
[[ $num -ge $limit ]] && break
done
printf %s "$buffer$line"
[[ $num -ge $limit ]]
}
function catless() {
local limit=$LINES buffer=''
# capture first $limit lines
# the \0 business is to guard the trailing newline
buffer=${"$(
cat_up_to_N_lines_and_exit_success_if_more $limit
ec=$?
printf '\0'
exit $ec)"%$'\0'}
use_pager=$?
if [[ $use_pager -eq 0 ]]; then
{ printf '%s' "$buffer"; cat } | less
else
printf '%s' "$buffer"
fi
}
Altri suggerimenti
La bandiera -X
potrebbe dare una mano (da meno (1)):
-X or --no-init Disables sending the termcap initialization and deinitialization strings to the terminal. This is sometimes desirable if the deinitialization string does something unnecessary, like clearing the screen.
Quindi, il seguente dovrebbe fare quello che vuoi:
export LESS="-E -X"
In alternativa, dal momento che vi piace --quit-se-un-schermo, si potrebbe invece:
export LESS="-F -X"
less
ha un'opzione --clear-screen
(disponibile anche come -c
. Si potrebbe voler controllare la variabile d'ambiente LESS $ per assicurarsi che lo fa non includono questa opzione. Il mio non e si comporta esattamente come si vogliono (non come si sta cercando di superare).
È possibile disattivare le opzioni impostate nella variabile $ LESS su un ad hoc utilizzando +
. Ad esempio:
less -+c shortfile
Si dovrebbe anche fare in modo che $TERM
sia impostata correttamente.
Se tutto il resto fallisce, guardare il $LESSOPEN
pre-processore e $LESSCLOSE
caratteristiche post-processore nella sezione "INPUT PREPROCESSOR" di man less
per vedere se questo ti porta ad un altro approccio.