Роздрукуйте лінії між (і виключаючи) двома шаблонами


13

Я надішлю форму за допомогою cURL, де частина вмісту надходить з іншого файлу, вибраного за допомогою sed

Якщо param1використовується шаблон узгодження рядків з іншого файлу sed, команда нижче працює добре:

curl -d param1="$(sed -n '/matchpattern/p' file.txt)" -d param2=value2 http://example.com/submit

Тепер переходимо до проблеми. Я хочу показати лише текст між двома відповідними шаблонами, за винятком самого відповідного шаблону.

Скажімо, file.txtмістить:

Bla bla bla
firstmatch
It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.
secondmatch
The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English.

Наразі багато команд "між двома відповідніми шаблонами" sedне видаляються firstmatchта secondmatch.

Я хочу, щоб результат став:

It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.

Відповіді:


15

Ось один із способів зробити це:

sed '1,/firstmatch/d;/secondmatch/,$d' 

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



5

Інше sedрішення не вдасться, якщо воно firstmatchвідбудеться в 1-му рядку 1 .

Нехай це буде просто, використовуйте один діапазон і порожній 2 регулярні виразки:
або друкуйте все в цьому діапазоні, виключаючи кінці діапазону (автоматичний друк вимкнено) 3 :

sed -n '/firstmatch/,/secondmatch/{//!p;}' infile

або, коротше, видаліть усе, що не знаходиться в цьому діапазоні, а також видаліть кінці діапазону:

sed '/firstmatch/,/secondmatch/!d;//d' infile


1: Причина полягає в тому, що якщо друга адреса - це повторне значення, то перевірка відповідності, що закінчується, почнеться з рядка, що слідує за рядком, який відповідає першій адресі .
Тому /firstmatch/ніколи не оцінюється для 1-го рядка вводу, sedвін просто видалить його, як він відповідає номеру рядка, 1,/RE/і перейде до другого рядка, де він перевіряє, чи відповідає рядок/firstpattern/

2: Коли REGEX порожній (тобто //) sedповодиться так, ніби був вказаний останній REGEX, використаний в останній застосованій команді (або як адреса, або як частина команди-замінника).

3: ;}синтаксис призначений для сучасних sedреалізацій; зі старшими використовуйте або новий рядок замість крапки з комою, або окремі вирази, наприкладsed -n -e '/firstmatch/,/secondmatch/{//!p' -e '}' infile


Чи можете ви пояснити, що //робиться (всередині {…})?
G-Man каже: "Відновіть Моніку"

Дякую, але ти потрапив у мою пастку. Я знаю, що //означає останній використаний регулярний вираз; з усього, що я прочитав, це повинно бути /secondmatch/. Я перевірив, перевіривши, чи працює ваша команда, і тому я прийшов до висновку, що вона функціонує як /firstmatch|secondmatch/(що ви підтвердили), але я не можу знайти жодної документації (навіть документа POSIX, з яким ви пов’язали чи GNU sed manual ), що описує таку поведінку. … (Продовжував)
G-Man каже: «Відновити Моніку»

(Продовження)… Розважальні експерименти: (I) В sed: (1) Якщо я це роблю /first/,4, то //діє так, як /first/. (2) Якщо я це роблю 2,/second/, тоді //виникає помилка "немає попереднього регулярного виразу". (Я вважаю це відвертим недотриманням зазначеної поведінки.) (3) Додавання --posixне змінює жодного з перерахованих. (II) В інших програмах: (4) В vi, після /first/,/second/, //такі дії /second/(а інші форми також є раціональною реалізацією документально підтвердженого правила). … (Продовжував)
G-Man каже: «Відновити Моніку»

(Продовження)… (5),  awkсхоже, не має поняття “останній використаний РЕ”; //відноситься до символів до або після будь-якого символу. (Я запрошую вас спробувати echo -- | awk '{ gsub(//, "cha"); print }'.)
G-Man каже: «Відновити Моніку»

Отже, ви читаєте "останній REGEX, використаний в останній команді", як "останній REGEX, використаний в останній команді", і ви (правильно) здогадалися, що це означає /first|second/. Щасливчик. Я згадую інші програми, щоб продемонструвати, що це не якась загальносистемна конвенція про регулярні вибори. Хто б не додав його, sedне намагався додати його vimтам, де це мало б такий же сенс. :-) ⁠
G-Man каже: "Відновити Моніку"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.