Перемикання починається з фіксованого тексту, аж до першого порожнього рядка


9

У мене такий файл prova.txt:

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

і мені потрібно виступити з "Почати, щоб захопити тут" до першого порожнього рядка. Вихід повинен бути таким:

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

Як ви бачите, що рядки після "Почати захоплювати тут" є випадковими, тому -A -B греп прапор не працює:

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

Чи можете ви допомогти мені знайти спосіб, який підхопить перший рядок, який буде схоплено (як "Почніть захоплювати звідси"), аж до порожнього рядка. Я не можу передбачити, скільки випадкових рядків у мене буде після "Почніть захоплювати звідси".

Будь-яке сумісне з Unix рішення цінується (grep, sed, awk краще perl або подібного).

ВЕДЕНО: після яскравої відповіді від @ john1024, я хотів би дізнатися, чи можна:

1 ° сортуйте блок (відповідно до Почати захоплювати звідси: 1, потім 1, а потім 2)

2 ° видаліть 4 (за алфавітом випадкові) лінії fix1, fix2, fix3, fix4, але завжди 4

3 ° з часом видалити випадкові дупи, як команда сортування -u

Кінцевий вихід повинен бути таким:

# 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

або

# 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

Другий вихід краще, ніж перший. Потрібна якась інша магія команди Unix.


1
Це дуже корисно для отримання сліду стека для певного потоку з виводу Java jstack. Радий, що я знайшов це запитання!
БенджамінБаллард

Відповіді:


13

Використання awk

Спробуйте:

$ 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/,/^$/визначає діапазон. Він починається з будь-якого рядка, який відповідає, Start to grabі закінчується першим порожнім рядком ^$, що далі.

Використання sed

З дуже подібною логікою:

$ 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

-nкаже седу нічого не друкувати, якщо ми прямо цього не попросимо. /Start to grab/,/^$/pповідомляє йому друкувати будь-які рядки в діапазоні, визначеному /Start to grab/,/^$/.


Ваше рішення ідеальне, я відредагував прохання щось додати. Relly високо оцінює вашу допомогу. Дякую
heisen

1

Я публікую альтернативне рішення, оскільки воно може бути корисним для деяких випадків використання людей. Це рішення не відповідає точно зазначеним вимогам, найкраще рішення див. У відповіді від @ John1024.

Ви можете використовувати awk, якщо роздільник записів встановлений у порожній рядок, awk інтерпретує їх як порожні рядки:

$ 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

Ця версія не зберігає пусті нові рядки у висновку. Він також покаже контекст перед матчем, якщо він присутній. Така поведінка може бути дуже корисною, коли ви хочете отримати щось у файлі, і ви хочете побачити новий розділений блок, до якого він входить, наприклад:

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

Наприклад, я вважаю це корисним під час збирання речей у iniфайлах.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.