Grep bắt đầu từ một văn bản cố định, cho đến dòng trống đầu tiên


9

Tôi có một tập tin prova.txtnhư thế này:

Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random2
random3
random4

extra1
extra2
bla

Start to grab from here: 2
fix1
fix2
fix3
fix4
random1546
random2561

extra2
bla
bla

Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random22131

và tôi cần phải chuyển từ "Bắt đầu lấy ở đây" đến dòng trống đầu tiên. Đầu ra phải như thế này:

Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random2
random3
random4

Start to grab from here: 2
fix1
fix2
fix3
fix4
random1546
random2561

Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random22131

Như bạn có thể thấy các dòng sau "Bắt đầu lấy ở đây" là ngẫu nhiên, vì vậy cờ -A -B grep không hoạt động:

cat prova.txt | grep "Start to grab from here" -A 15 | grep -B 15 "^$" > output.txt

Bạn có thể giúp tôi tìm cách bắt được dòng đầu tiên sẽ được lấy (như "Bắt đầu lấy từ đây"), cho đến khi một dòng trống. Tôi không thể dự đoán mình sẽ có bao nhiêu dòng ngẫu nhiên sau "Bắt đầu lấy từ đây".

Bất kỳ giải pháp tương thích unix nào cũng được đánh giá cao (grep, sed, awk tốt hơn perl hoặc tương tự).

EDITED: sau phản hồi xuất sắc của @ john1024, tôi muốn biết liệu có thể:

Sắp xếp 1 ° khối (theo Bắt đầu để lấy từ đây: 1 rồi 1 rồi 2)

2 ° xóa 4 dòng (ngẫu nhiên theo thứ tự chữ cái) fix1, fix2, fix3, fix4 nhưng luôn là 4

3 ° cuối cùng loại bỏ các bản sao ngẫu nhiên, như lệnh sort -u

Shoul đầu ra cuối cùng là như thế này:

# fix lines removed - match 1 first time
Start to grab from here: 1
random1
random2
random3
random4

#fix lines removed - match 1 second time
Start to grab from here: 1
#random1 removed cause is a dupe
random22131

#fix lines removed - match 2 that comes after 1
Start to grab from here: 2
random1546
random2561

hoặc là

# fix lines removed - match 1 first time and the second too
Start to grab from here: 1
random1
random2
random3
random4
#random1 removed cause is a dupe
random22131

#fix lines removed - match 2 that comes after 1
Start to grab from here: 2
random1546
random2561

Đầu ra thứ hai tốt hơn cái đầu tiên. Một số phép thuật lệnh unix khác là cần thiết.


1
Điều này thực sự hữu ích cho việc lấy dấu vết ngăn xếp cho một luồng cụ thể từ đầu ra jstack java. Vui mừng tôi tìm thấy câu hỏi này!
BenjaminBallard

Câu trả lời:


13

Sử dụng awk

Thử:

$ awk '/Start to grab/,/^$/' prova.txt
Start to grab from here: 1
random1
random2
random3
random4

Start to grab from here: 2
random1546
random2561

Start to grab from here: 3
random45
random22131

/Start to grab/,/^$/định nghĩa một phạm vi. Nó bắt đầu với bất kỳ dòng nào khớp Start to grabvà kết thúc bằng dòng trống đầu tiên ^$, tiếp theo.

Sử dụng sed

Với logic rất giống nhau:

$ sed -n '/Start to grab/,/^$/p' prova.txt
Start to grab from here: 1
random1
random2
random3
random4

Start to grab from here: 2
random1546
random2561

Start to grab from here: 3
random45
random22131

-nnói với sed không được in bất cứ thứ gì trừ khi chúng tôi yêu cầu rõ ràng. /Start to grab/,/^$/pbảo nó in bất kỳ dòng nào trong phạm vi được xác định bởi /Start to grab/,/^$/.


Giải pháp của bạn là hoàn hảo, tôi đã chỉnh sửa yêu cầu của tôi để thêm một cái gì đó. Đáng tin cậy giúp đỡ của bạn. Cảm ơn bạn
heisen

1

Tôi đang đăng một giải pháp thay thế vì nó có thể hữu ích cho một số trường hợp sử dụng của mọi người. Giải pháp này không tuân thủ chính xác các yêu cầu đã nêu, để có giải pháp tốt nhất, hãy xem câu trả lời từ @ John1024.

Bạn có thể sử dụng awk với Bộ tách bản ghi được đặt thành một chuỗi trống, awk sẽ diễn giải những điều này dưới dạng dòng mới:

$ awk '/Start/' RS= prova.txt 
Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random2
random3
random4
Start to grab from here: 2
fix1
fix2
fix3
fix4
random1546
random2561
Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random22131

Phiên bản này không bảo toàn các dòng mới trống trong đầu ra. Nó cũng sẽ hiển thị bối cảnh trước trận đấu nếu có. Hành vi này có thể rất hữu ích khi grepping cho một cái gì đó trong một tệp và bạn muốn xem khối giới hạn dòng mới, nó là một phần của, ví dụ:

$ awk '/random1546/' RS= prova.txt 
Start to grab from here: 2
fix1
fix2
fix3
fix4
random1546
random2561

Ví dụ, tôi thấy điều này hữu ích khi grepping cho những thứ trong initập tin.

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.