Metodo Bash per visualizzare l'inizio e la fine del file


8

Sui cluster basati su coda, la coda dei lavori in sospeso viene mostrata da un comando, ad esempio showqueue.

Il comando restituisce, in colonne, un elenco di dati ragionevoli come nomi, ecc., Ma le colonne / i dati non contano davvero per la domanda.

Mi piace usare l'utilità watchcome watch showqueuea volte (con un alias di alias watch="watch "forzare l'espansione dell'alias del mio comando da guardare). Ci sono dati preziosi (Lavori in esecuzione), nelle prime poche righe, quindi in attesa di lavori, ecc. E alcuni preziosi riassunti alla fine.

Tuttavia, a volte l'output di showqueue scompare dallo schermo (Incredibile, lo so)! Idealmente, vorrei un modo per essere in grado di vedere l'inizio e la fine del file allo stesso tempo.

Il migliore che ho finora è:, showqueue > file; head -n 20 file > file2; echo "..." >> file2 ; tail -n 20 file >> file2; cat file2e usando watchun alias di quello.

Qualcuno sa qualcosa di un po 'più flessibile o single-utility? La mia soluzione diventa un po 'più cattiva con i loop bash per rendere la "..." rottura multilinea, non è adattabile al ridimensionamento della finestra del terminale e sono sicuro che ci sia più di quello che mi sono perso.

Eventuali suggerimenti?


Chiuso come duplicato, ma la domanda condivide solo le somiglianze (la mia riguarda più un comando, ho imparato e non i file), e le risposte qui non sono state mostrate lì, ma se insisti
MadisonCooper

2
Giusto. Ho riaperto Nota che la risposta che hai accettato funzionerà solo per output di grandi dimensioni come indicato nella mia risposta in Command per visualizzare le prime e le ultime righe di un file (prova seq 30 | (head && tail)ad esempio).
Stéphane Chazelas,

2
Intendevo quella risposta . Che domande e risposte ha due mie risposte perché un'altra domanda è stata unita (vedi cronologia delle domande )
Stéphane Chazelas,

Risposte:


14

Stai cercando di fare qualcosa di simile al seguente? Mostra l'output sia della testa che della coda.

$ showqueue | (head && tail)

6
Alcune implementazioni di headpossono leggere più di 10 righe e non lasciano nulla tailda leggere. L'utilità non dovrebbe farlo e credo che gli strumenti GNU si comportino bene in questo senso. Utilizzare head; echo '...'; tailper inserire anche i punti.
Kusalananda

Sì, combinato con il commento di @ Kusalananda è molto più conciso della mia soluzione. Contrassegnerò come corretto per ora! Grazie.
MadisonCooper il

4
@Kusalananda, no, sul mio sistema, GNU head (coreutils 8.26) legge blocchi di 8192 byte. Non provare a cercare di nuovo, ma ovviamente non può in caso di un tubo. Comunque, c'è davvero un requisito per headnon leggere troppo? (lo stesso su Mac, sembra letto da blocchi)
ilkkachu il

2
@ilkkachu sì, anche se si trova la parte di coda è occasionalmente vuota anche su output sufficientemente lungo (lo so da quando sto usando head -n 35, ed è pieno), ma per fortuna è solo una comodità da guardare e posso aspettare 3 secondi per un aggiornamento, se necessario.
MadisonCooper il

3
@Kusalananda, POSIX consente alle implementazioni di farlo quando l'input non è ricercabile e la maggior parte delle implementazioni lo fanno. Non farlo significherebbe leggere un byte alla volta, il che sarebbe molto inefficiente (o rimettere i dati sulla pipe dove supportati che causerebbero ogni sorta di problemi diversi). L'unica headimplementazione che conosco che legge un byte alla volta per evitare di leggere oltre la decima riga è headincorporata in ksh93 .
Stéphane Chazelas,

2

Usando il tuo stesso approccio, usando un file temporaneo, ma facendolo leggermente più breve:

showqueue >/tmp/q.out; head -n 20 /tmp/q.out; echo '...'; tail -n 20 /tmp/q.out

Ciò non risentirebbe degli stessi problemi discussi in un'altra risposta , ma potrebbe mostrare le stesse linee due volte se l'output fosse inferiore a 40 righe.


+1 Stavo pensando alla stessa soluzione con la leggera variazione dell'utilizzo teeper consentire all'output di entrare direttamente heade utilizzare solo l'output salvato per tail.
Joe,

2

soluzione awk per un numero arbitrario di linee mostrate dalla testa e dalla coda (modifica n=3per impostare la quantità):

$ seq 99999 | awk -v n=3 'NR <= n; NR > n { a[NR] = $0; delete a[NR-n]; } 
     END { print "..."; for (i = NR-n+1; i <= NR; i++) if (i in a) print a[i]; }'
1
2
3
...
99997
99998
99999

Come è scritto, le parti testa e coda non si sovrapporranno, anche se l'input è più corto delle 2*nlinee.

In alcune implementazioni awk, anche l'uso for (x in a) print a[x];nella ENDparte funziona. Ma in generale, non è garantito che le voci dell'array vengano restituite nell'ordine corretto e, ad esempio, non lo fanno.


Se mè il numero di righe nel file e m < 2n, verranno stampate 2n - mrighe vuote. Guarda anche qui ;-). for (x in a)eseguirà l'iterazione solo in GNU awk ; se ritieni che funzioni anche tu mawk, prova con> 10 valori.
mosvy,

@mosvy, oh, whoops, ho dimenticato di ricontrollare che dopo aver realizzato x in anon era giusto. Risolto ora, grazie. C'è anche un'altra risposta imbarazzante nella domanda a cui Stéphane è legato. Mi piace il trucco del modulo, però!
ilkkachu,

0

Puoi usare un semplice script awk. Aggiunto buffer circolare lì n = 3 è per le ultime 3 righe

awk 'NR<=n {print $0} { A[NR%n]=$0 } END { for (i=1; i<=n; ++i) if (NR+i>2*n)print A[(NR+i)%n] }' n=3 < <( seq 10 )

Dopo l'aggiornamento non è più semplice però,


1
Ciò mostrerebbe solo la prima e l'ultima riga. Per mostrare qualcosa di più, dovresti cambiare NR==1in NR <= 10(o qualcosa del genere), e quindi raccogliere le linee in un buffer (circolare?) Che successivamente emetti nel ENDblocco.
Kusalananda

Sì, fammi aggiornare
Abdurrahim,

Questo stamperà alcune righe due volte quando il numero di righe sarà inferiore a 2 * n.
mosvy,

:) ok aggiungo che anche adesso sono curioso di sapere cosa troverai dopo: D
Abdurrahim
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.