У меня есть файл, 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 grep не работает:
cat prova.txt | grep "Start to grab from here" -A 15 | grep -B 15 "^$" > output.txt
Можете ли вы помочь мне найти способ, который поймает первую строку, которая будет захвачена (как «Начать захватывать отсюда»), до пустой строки. Я не могу предсказать, сколько случайных строк у меня будет после «Начать отсюда».
Любое решение, совместимое с Unix, приветствуется (grep, sed, awk лучше, чем perl или аналогичный).
Отредактировано: после блестящего ответа @ john1024, я хотел бы знать, возможно ли:
1 ° Сортировка блока (в соответствии с Start начать отсюда: 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.
источник
Ответы:
Использование awk
Пытаться:
/Start to grab/,/^$/
определяет диапазон. Он начинается с любой совпадающей строкиStart to grab
и заканчивается первой пустой строкой,^$
следующей за ней.Используя sed
С очень похожей логикой:
-n
говорит sed не печатать ничего, если мы явно не попросим об этом./Start to grab/,/^$/p
говорит ему напечатать любые строки в диапазоне, определенном/Start to grab/,/^$/
.источник
Я публикую альтернативное решение, так как оно может быть полезно для некоторых людей. Это решение не полностью соответствует заявленным требованиям, для лучшего решения см. Ответ @ John1024.
Вы можете использовать awk с разделителем записей, установленным на пустую строку, awk будет интерпретировать их как пустые строки:
Эта версия не сохраняет пустые символы новой строки в выводе. Он также покажет контекст перед совпадением, если он присутствует. Такое поведение может быть очень полезным, когда нужно найти что-то в файле, и вы хотите увидеть разделенный строкой блок, частью которого он является, например:
Например, я считаю это полезным при поиске вещей в
ini
файлах.источник