ОТРЕДАКТИРОВАНО: после блестящего ответа @john1024 я хотел бы узнать, возможно ли:

ОТРЕДАКТИРОВАНО: после блестящего ответа @john1024 я хотел бы узнать, возможно ли:

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

и мне нужно grep out от "Start to grab here" до первой пустой строки. Вывод должен быть таким:

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

Как вы видите, строки после «Start to grab here» случайны, поэтому флаг grep -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° в конечном итоге удалить случайные дубликаты, например, команду sort -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

Использование 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сообщает sed, что не нужно ничего печатать, пока мы явно не попросим его об этом. /Start to grab/,/^$/pсообщает ему, что нужно печатать все строки в диапазоне, определенном /Start to grab/,/^$/.

решение2

Я публикую альтернативное решение, так как оно может быть полезным для некоторых случаев использования. Это решение не совсем соответствует заявленным требованиям, для лучшего решения см. ответ от @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файлах.

Связанный контент