Phương pháp Bash để xem đầu và cuối tệp


8

Trên các cụm dựa trên hàng đợi, hàng đợi của các công việc đang chờ xử lý được hiển thị từ một lệnh, giả sử showqueue.

Lệnh trả về, trong các cột, một danh sách các dữ liệu hợp lý như tên, v.v., nhưng các cột / dữ liệu không thực sự quan trọng đối với câu hỏi.

Tôi thích sử dụng tiện ích watchnhư watch showqueueđôi khi (với bí danh alias watch="watch "để buộc mở rộng bí danh lệnh của tôi để xem). Có dữ liệu có giá trị (Chạy công việc), trong một vài dòng đầu tiên, sau đó là các công việc đang chờ xử lý, v.v. và một số tóm tắt có giá trị ở cuối.

Tuy nhiên, đôi khi đầu ra của showqueue tắt màn hình (Không thể tin được, tôi biết)! Lý tưởng nhất, tôi muốn một số cách để có thể xem phần đầu và phần cuối của tệp cùng một lúc.

Điều tốt nhất tôi có cho đến nay là: showqueue > file; head -n 20 file > file2; echo "..." >> file2 ; tail -n 20 file >> file2; cat file2và sử dụng watchbí danh đó.

Có ai biết bất cứ điều gì linh hoạt hơn hoặc tiện ích đơn lẻ không? Giải pháp của tôi trở nên khó khăn hơn một chút với các vòng lặp bash để làm cho "..." bị phá vỡ đa dạng, nó không thích ứng với việc thay đổi kích thước cửa sổ đầu cuối, và tôi chắc chắn rằng tôi đã bỏ lỡ nhiều hơn.

Bất kỳ đề xuất?


Đóng như là trùng lặp, nhưng câu hỏi chỉ chia sẻ những điểm tương đồng (Tôi nói nhiều hơn về một lệnh, tôi đã học chứ không phải các tệp) và câu trả lời ở đây không hiển thị ở đó, nhưng nếu bạn nhấn mạnh
MadisonCooper 26/03/19

2
Đủ công bằng. Tôi đã mở lại. Lưu ý rằng câu trả lời mà bạn đã chấp nhận sẽ chỉ hoạt động đối với các đầu ra lớn như được ghi chú trong câu trả lời của tôi tại Command để hiển thị một vài dòng đầu tiên và cuối cùng của một tệp ( seq 30 | (head && tail)ví dụ thử ).
Stéphane Chazelas

2
Tôi có nghĩa là câu trả lời . Câu hỏi và trả lời đó có hai câu trả lời của tôi vì một câu hỏi và trả lời khác đã được hợp nhất với nó (xem lịch sử câu hỏi )
Stéphane Chazelas

Câu trả lời:


14

Bạn đang tìm cách để làm một cái gì đó như sau? Hiển thị đầu ra từ cả đầu và đuôi.

$ showqueue | (head && tail)

6
Một số triển khai headcó thể đọc hơn 10 dòng và không để lại gì tailđể đọc. Tiện ích không phải làm điều đó và tôi tin rằng các công cụ GNU hoạt động tốt trong khía cạnh này. Sử dụng head; echo '...'; tailđể có được các dấu chấm trong đó là tốt.
Kusalananda

Vâng, kết hợp với nhận xét của @ Kusalananda, nó ngắn gọn hơn nhiều so với giải pháp của tôi. Bây giờ tôi sẽ đánh dấu là chính xác! Cảm ơn.
MadisonCooper

4
@Kusalananda, không, trên hệ thống của tôi, đầu GNU (coreutils 8.26) đọc các khối 8192 byte. Nó cố gắng tìm kiếm trở lại, nhưng rõ ràng là không thể trong trường hợp đường ống. Mặc dù vậy, có thực sự có một yêu cầu headđể không đọc quá nhiều? (tương tự trên Mac, nó dường như được đọc theo khối)
ilkkachu

2
@ ilk giây để làm mới nếu cần.
MadisonCooper

3
@Kusalananda, POSIX cho phép triển khai thực hiện điều đó khi đầu vào không thể tìm kiếm và hầu hết các triển khai thực hiện. Không làm điều đó có nghĩa là đọc một byte tại một thời điểm sẽ rất không hiệu quả (hoặc đưa dữ liệu trở lại đường ống nơi được hỗ trợ sẽ gây ra tất cả các loại vấn đề khác nhau). Việc headtriển khai duy nhất tôi biết rằng đọc một byte mỗi lần để tránh đọc qua dòng mới thứ 10 là headnội dung của ksh93 .
Stéphane Chazelas

2

Sử dụng phương pháp tương tự như bạn, sử dụng tệp tạm thời, nhưng thực hiện ngắn hơn một chút:

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

Điều này sẽ không gặp phải các vấn đề tương tự như được thảo luận dưới một câu trả lời khác , nhưng thể sẽ hiển thị cùng một dòng hai lần nếu đầu ra ngắn hơn 40 dòng.


+1 Tôi đã nghĩ đến cùng một giải pháp với sự thay đổi nhỏ của việc sử dụng teeđể cho đầu ra đi thẳng vào headvà chỉ sử dụng đầu ra đã lưu cho tail.
Joe

2

giải pháp awk cho một số dòng tùy ý hiển thị từ đầu và đuôi (thay đổi n=3để đặt số lượng):

$ 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

Như đã viết, phần đầu và đuôi sẽ không trùng nhau, ngay cả khi đầu vào ngắn hơn 2*ncác dòng.

Trong một số triển khai awk, sử dụng for (x in a) print a[x];trong ENDphần cũng hoạt động. Nhưng nói chung, nó không được đảm bảo để trả về các mục mảng theo đúng thứ tự và không ví dụ như mawk.


Nếu mlà số dòng trong tệp, và m < 2n, nó sẽ in 2n - mcác dòng trống. Cũng đã xem ở đây ;-). for (x in a)sẽ lặp lại theo thứ tự chỉ trong GNU awk ; nếu bạn nghĩ rằng nó cũng hoạt động mawk, hãy kiểm tra với> 10 giá trị.
mosvy 26/03/19

@mosvy, oh, rất tiếc, tôi đã quên kiểm tra lại rằng sau khi nhận ra điều x in ađó không đúng. Đã sửa bây giờ, cảm ơn. Ngoài ra còn có một câu trả lời awk khác trong câu hỏi Stéphane liên kết đến. Tôi thích thủ thuật modulo, mặc dù!
ilkkachu

0

Bạn có thể sử dụng kịch bản awk đơn giản. Đã thêm bộ đệm vòng tròn có n = 3 cho 3 dòng cuối cùng

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 )

Sau khi cập nhật nó không còn đơn giản nữa,


1
Điều này sẽ chỉ hiển thị dòng đầu tiên và cuối cùng. Để hiển thị nhiều hơn thế, bạn sẽ phải thay đổi NR==1thành NR <= 10(hoặc một cái gì đó), sau đó thu thập các dòng vào bộ đệm (tròn?) Mà sau này bạn xuất ra trong ENDkhối.
Kusalananda

có, hãy để tôi cập nhật
Abdurrahim

Điều này sẽ in một số dòng hai lần khi đó số lượng dòng ít hơn 2 * n.
mosvy 26/03/19

:) ok thêm vào đó cũng như bây giờ tôi tò mò bạn sẽ tìm thấy gì tiếp theo: D
Abdurrahim
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.