Metode Bash untuk melihat awal dan akhir file

8

Pada kluster berbasis antrian, Antrian pekerjaan yang tertunda ditampilkan dari sebuah perintah, katakanlah showqueue.

Perintah mengembalikan, dalam kolom, daftar data yang masuk akal seperti nama, dll, tetapi kolom / data tidak terlalu penting untuk pertanyaan.

Saya suka menggunakan utilitas watchseperti watch showqueuedi kali (dengan alias alias watch="watch "untuk memaksa alias perluasan perintah saya untuk menonton). Ada data berharga (Menjalankan pekerjaan), di beberapa baris pertama, lalu pekerjaan yang tertunda, dll, dan beberapa ringkasan berharga di akhir.

Namun, kadang-kadang output showqueue keluar dari layar (Luar biasa, saya tahu)! Idealnya, saya ingin beberapa cara untuk dapat melihat awal dan akhir file pada saat yang sama.

Yang terbaik yang saya miliki sejauh ini adalah:, showqueue > file; head -n 20 file > file2; echo "..." >> file2 ; tail -n 20 file >> file2; cat file2dan menggunakan watchalias itu.

Adakah yang tahu tentang sesuatu yang sedikit lebih fleksibel atau utilitas tunggal? Solusi saya menjadi sedikit nastier dengan loop bash untuk membuat "..." istirahat multiline, itu tidak adaptif untuk mengubah ukuran jendela terminal sama sekali, dan saya yakin ada lebih banyak yang saya lewatkan.

Ada saran?

MadisonCooper
sumber
Ditutup sebagai duplikat, tetapi pertanyaannya hanya berbagi kesamaan (Tambang lebih tentang perintah, saya pelajari, dan bukan file), dan jawaban di sini tidak muncul di sana, tetapi jika Anda bersikeras
MadisonCooper
2
Cukup adil. Saya telah membuka kembali. Perhatikan bahwa jawaban yang Anda terima hanya akan berfungsi untuk keluaran besar seperti yang tercantum pada jawaban saya di Command untuk menampilkan beberapa baris pertama dan terakhir beberapa file (coba seq 30 | (head && tail)misalnya).
Stéphane Chazelas
2
Maksud saya jawaban itu . Tanya Jawab itu memiliki dua jawaban saya karena tanya jawab lain digabungkan dengannya (lihat riwayat pertanyaan )
Stéphane Chazelas

Jawaban:

14

Apakah Anda ingin melakukan sesuatu seperti yang berikut ini? Menunjukkan output dari kepala dan ekor.

$ showqueue | (head && tail)
Timothy Pulliam
sumber
6
Beberapa implementasi headdapat membaca lebih dari 10 baris dan tidak meninggalkan apa pun untuk taildibaca. Utilitas tidak seharusnya melakukan itu dan saya percaya bahwa alat GNU berperilaku baik dalam hal ini. Gunakan head; echo '...'; tailuntuk mendapatkan titik-titik di sana juga.
Kusalananda
Ya, dikombinasikan dengan komentar @ Kusalananda, ini jauh lebih ringkas daripada solusi saya. Saya akan menandai sebagai benar untuk saat ini! Terima kasih.
MadisonCooper
4
@ Kusalananda, tidak, di sistem saya, kepala GNU (coreutils 8.26) membaca blok 8192 byte. Memang mencoba untuk mencari kembali, tetapi jelas tidak bisa dalam kasus pipa. Meski begitu, apakah benar-benar ada persyaratan untuk headtidak membaca berlebihan? (sama pada Mac, tampaknya dibaca oleh blok)
ilkkachu
2
@ilkkachu ya, meskipun berdiri bagian ekor kadang-kadang kosong bahkan pada output yang cukup panjang (saya tahu karena saya menggunakan kepala -n 35, dan itu penuh), tapi untungnya itu hanya kenyamanan untuk menonton dan saya bisa menunggu 3 detik untuk penyegaran jika diperlukan.
MadisonCooper
3
@ Kusalananda, POSIX memungkinkan implementasi untuk melakukan itu ketika input tidak dapat dicari dan sebagian besar implementasi melakukannya. Tidak melakukan itu berarti membaca satu byte pada suatu waktu yang akan sangat tidak efisien (atau meletakkan kembali data ke pipa di mana didukung yang akan menyebabkan segala macam masalah yang berbeda). Satu-satunya headimplementasi yang saya tahu yang membaca satu byte pada satu waktu untuk menghindari membaca melewati baris ke-10 adalah headbuiltin ksh93 .
Stéphane Chazelas
2

Menggunakan pendekatan yang sama seperti Anda, menggunakan file sementara, tetapi melakukannya sedikit lebih pendek:

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

Ini tidak akan menderita dari masalah yang sama seperti yang dibahas di bawah jawaban lain , tetapi mungkin akan menunjukkan baris yang sama dua kali jika output lebih pendek dari 40 baris.

Kusalananda
sumber
+1 Saya sedang memikirkan solusi yang sama dengan sedikit variasi penggunaan teeuntuk membiarkan output langsung masuk ke headdan hanya menggunakan output yang disimpan untuk tail.
Joe
2

solusi awk untuk jumlah garis sewenang-wenang yang ditunjukkan dari kepala dan ekor (ubah n=3untuk mengatur jumlah):

$ 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

Seperti yang tertulis, bagian kepala dan ekor tidak akan tumpang tindih, bahkan jika input lebih pendek dari 2*ngaris.

Dalam beberapa implementasi awk, menggunakan for (x in a) print a[x];di ENDbagian juga bekerja. Tetapi secara umum, itu tidak dijamin untuk mengembalikan entri array dalam urutan yang benar, dan tidak dalam mis. Mawk.

ilkkachu
sumber
Jika mjumlah baris dalam file, dan m < 2n, itu akan mencetak 2n - mbaris kosong. Lihat juga di sini ;-). for (x in a)akan beralih hanya dalam GNU awk ; jika Anda berpikir itu berfungsi mawkjuga, uji dengan> 10 nilai.
Mosvy
@ Mosvy, oh, wah, saya lupa memeriksa kembali bahwa setelah menyadari x in aitu tidak benar. Tetap sekarang, terima kasih. Ada juga jawaban awk lain dalam pertanyaan yang dikaitkan dengan Stéphane. Saya suka trik modulo!
ilkkachu
0

Anda dapat menggunakan skrip awk sederhana. Menambahkan buffer lingkaran di sana n = 3 untuk 3 baris terakhir

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 )

Namun setelah pembaruannya tidak sederhana lagi,

Abdurrahim
sumber
1
Ini hanya akan menunjukkan baris pertama dan terakhir. Untuk menunjukkan lebih dari itu, Anda harus mengubah NR==1ke NR <= 10(atau sesuatu), dan kemudian mengumpulkan garis menjadi buffer (melingkar?) Yang nanti Anda hasilkan di ENDblok.
Kusalananda
ya biarkan saya memperbarui
Abdurrahim
Ini akan mencetak beberapa baris dua kali ketika jumlah baris kurang dari 2 * n.
Mosvy
:) ok menambahkan itu juga sekarang saya ingin tahu apa yang akan Anda temukan berikutnya: D
Abdurrahim