Как сопоставить все, начиная с последнего разделителя YAML и далее

Я обычно пользуюсь grep искать шаблон в строке. Однако в этом конкретном случае я должен идентифицировать заголовок YAML, также он заканчивается тройной чертой.

Мой файл test.info имеет следующий контент

---
title: dont't know
draft: true
---
this is a test to add some extra content

Я хочу следующий вывод, то есть все, начиная с последнего разделителя YAML и до конца файла:

this is a test to add some extra content

Когда я вхожу в тире, bash возвращает следующую ошибку:

$ cat test.info | grep '---' -A1
grep: unrecognized option `---'

Я безуспешно пытался "сбежать" от черточек. Любая идея? Это для BSD grep. Меня смущает то, что я могу получить то, что хочу, если сделаю что-то вроде следующего.

$ cat test.info | grep 'this' -A1

Проблема в том, что я не знаю, какое первое слово.

Я могу выполнить поиск файла в соответствии с рекомендациями, но инструмент возвращает шаблон, а не все сразу после:

$ grep -m 1 -e '---' test.info 
---
$ grep -- --- test.info | tail -1
---

6 ответов

Решение

Так что, не принимая кредиты, как я не хочу, я просто публикую решение, которое работало на моем Mac благодаря KasiyA

tail -r file| awk '/---/ {exit} {print}'| tail -r

Как насчет этой команды?

tac file| awk '/---/ {exit} {print}'|tac

На OSX просто замените оба tac команды с tail -r

От человека так:

 tac - объединяет и печатает файлы в обратном порядке - в обратном порядке команды cat;)

Выход из tac file:

next line
this is a test to add some extra content
---
draft: true
title: dont't know
---

Команда awk awk '/---/ {exit} {print}' печатает все строки, пока не будет найден первый соответствующий шаблон.

Выход:

next line
this is a test to add some extra content

тогда беги tac снова введите команду, чтобы вернуться к значению по умолчанию.

Выход:

this is a test to add some extra content
next line

Использование awk:

awk 'END{print}' RS='---' file

RS определяет --- в качестве разделителя записей и с END{print} мы печатаем только последнюю запись.

Используя sed:

sed -r ':a;$!{N;ba};s:^(.*\n?)---::' file
$ line=$(grep -n - --- test.info | tail -n 1 | cut -d: -f1);tail -n +$(( $line + 1)) test.info 
это тест для добавления дополнительного контента

Необходимо добавить соответствующую проверку ошибок, как в if $line 'not numeric' ...

Первоначальная проблема заключается в том, что вам нужно сбежать - или скажите программе, что это не вариант:

$ grep -n - --- test.info
1:---
4:---

Большая часть (?) Программного обеспечения GNU имеет "-" в качестве опции; говорит прекратить анализ для получения дополнительных опций после этого момента.

Замечания:
$ grep --version
должен сказать, если это утилита GNU grep или нет.

$ grep -h
или же
$ grep --help
обычно говорит варианты, которые он понимает.

Я вижу как минимум два разных способа сделать это. На самом деле вам нужно убежать от первого "-"

Используя опцию -e:

grep -e "---" test.info

Выход из первого "-" с обратной косой чертой:

grep "\---" test.info

Обращаясь к одному аспекту вашего (теперь оригинального) вопроса.

(И ваши новые вопросы по-прежнему говорят о grep и -A1 и делают вид, что вы не можете найти способ указать 3 дефиса, и это просто неправильно, потому что в ваших комментариях вы показали, что можете).

[ваш оригинальный вопрос спрашивал, как показать результаты ОТ точки. когда на самом деле вы хотите ОТ ПОСЛЕ. В вашем новом вопросе все еще говорится "от", я обновил его до "от после"

Если похоже, что grep и -A1 - это не то, что вам нужно, хотя это все еще упоминается даже в вашем обновленном вопросе

Я не вижу смешных результатов. Возможно, вы можете вставить результаты, которые вы считаете смешными. [теперь у вас есть]

Если вы выполните grep pattern -A1, то он выдает шаблон, за которым следует следующая строка. И это свалки -- после каждого матча.

например

$ cat t3.info
,,,
qwerty
uiop
,,,




werwer
werwer
,,,,,
werwerwer
werwerwer
werwerwer
,,,,



$ cat t3.info | grep -P ',,,' -A1
,,,
qwerty
--
,,,

--
,,,,,
werwerwer
--
,,,,



$

Вы можете выполнить grep -P '(?=---)...' -A1 Еще одна вещь, которую вы можете попробовать, это grep -P '\x2d{3}' -A1

И если ваш файл имеет ---

$ cat t3.info
---
qwerty
uiop
---




werwer
werwer
---
werwerwer
werwerwer
werwerwer
---

Конечно, это не работает

$ cat t3.info | grep -P '---' -A1 grep: нераспознанная опция '---' Использование: grep [ОПЦИЯ]... ШАБЛОН [ФАЙЛ]... Попробуйте 'grep --help' для получения дополнительной информации.

Но это работает

$ cat t3.info | grep -P '\---' -A1
---
qwerty
--
---

--
---
werwerwer
--
---

и это работает

$ cat t3.info | grep -P '(?=\x2d{3})...' -A1
---
qwerty
--
---

--
---
werwerwer
--
---

grep версия 2.16

$ grep --version
grep (GNU grep) 2.16

Если вы не хотите включать ваш шаблон, тогда какой бы вариант вы не использовали, он не будет -A1, и я не понимаю, почему у вас возникают проблемы с соответствием ---

Может случиться так, что для того, чтобы делать то, что вы хотите, с помощью grep или чего-то подобного grep, вам нужно сопоставить новую строку с регулярным выражением egeg с положительным lookbehind.. for ---\n, но, очевидно, grep не может сопоставить новые строки, в этом случае вы можете повезет больше с pcregrep https://stackoverflow.com/questions/2686147/how-to-find-patterns-across-multiple-lines-using-grep или другим способом. Еще один вопрос, как вы можете сопоставить то, что следует на линии после паттерна.

Другие вопросы по тегам