Как удалить все строки до первого и после последнего появления строки? - PullRequest
7 голосов
/ 21 июня 2020

cat grab.txt

My Dashboard
Fnfjfjf. random test
00:50

1:01:56
My Notes
No data found.

                                
Change Language                                                                                                                  + English                                                          

Submit


Estimation of Working Capital Lecture 1

Estimation of Working Capital Lecture 2

Estimation of Working Capital Lecture 3

Money Market Lecture 254

Money Market Lecture 255

Money Market Lecture 256

International Trade Lecture 257

International Trade Lecture 258

International Trade Lecture 259
Terms And Conditions
84749473837373
Random text fifjfofifofjfkfkf

Мне нужно отфильтровать этот текст после выполнения следующих действий

  1. Удалить все строки перед первым вхождением слова - Лекция
  2. Удалить все строки после последнего вхождения слова - Лекция
  3. Удалить все пустые строки

Ожидаемый результат

Estimation of Working Capital Lecture 1
Estimation of Working Capital Lecture 2
Estimation of Working Capital Lecture 3
Money Market Lecture 254
Money Market Lecture 255
Money Market Lecture 256
International Trade Lecture 257
International Trade Lecture 258
International Trade Lecture 259

Что я пробовал до сих пор?

cat grab.txt | sed -r '/^\s*$/d; /Lecture/,$!d'

После небольшого поиска и некоторой пробной ошибки я могу удалить пустые строки и удалить все строки до первого появления, но не могу удалить все строки после последнего появления.

Примечание. Даже если моя существующая команда использует sed, все в порядке, если ответ в awk, perl или grep

Ответы [ 3 ]

6 голосов
/ 21 июня 2020

Не могли бы вы попробовать следующее. Написано и протестировано на показанных образцах с GNU awk.

awk '
/Lecture/{
  found=1
}
found && NF{
  val=(val?val ORS:"")$0
}
END{
  if(val){
    match(val,/.*Lecture [0-9]+/)
    print substr(val,RSTART,RLENGTH)
  }
}'  Input_file

Пояснение: Добавление подробного объяснения вышеизложенного.

awk '                                        ##Starting awk program from here.
/Lecture/{                                   ##Checking if a line has Lecture keyword then do following.
  found=1                                    ##Setting found to 1 here.
}
found && NF{                                 ##Checking if found is SET and line is NOT NULL then do following.
  val=(val?val ORS:"")$0                     ##Creating va and keep adding its value in it.
}
END{                                         ##Starting END block of this code here.
  if(val){                                   ##Checking condition if val is set then do following.
    match(val,/.*Lecture [0-9]+/)            ##Matching regex till Lecture digits in its value.
    print substr(val,RSTART,RLENGTH)         ##Printing sub string of matched values here to print only matched values.
  }
}' Input_file                                ##Mentioning Input_file name here.
5 голосов
/ 21 июня 2020

Простое использование grep 'Lecture' file с вводом, которое вы показали в file, будет работать:

$ grep 'Lecture' file
Estimation of Working Capital Lecture 1
Estimation of Working Capital Lecture 2
Estimation of Working Capital Lecture 3
Money Market Lecture 254
Money Market Lecture 255
Money Market Lecture 256
International Trade Lecture 257
International Trade Lecture 258
International Trade Lecture 259

( примечание: это просто захватит все строки, содержащие Lecture. См. Ответ @ RavinderSingh13 для защиты от не- Lecture строк между ними)

2 голосов
/ 21 июня 2020

Вы можете заменить совпадения следующего регулярного выражения (с установленным многострочным флагом) пустыми строками, используя выбранный вами инструмент. Механизм регулярных выражений должен поддерживать только отрицательный просмотр вперед.

\A(?:^(?!.*\bLecture\b).*\r?\n)*|^\r?\n|^.*\r?\n(?![\s\S]*\bLecture\b)

Запустите свой механизм!

Механизм регулярных выражений выполняет следующие операции.

\A                  : match beginning of string (not line)    
(?:                 : begin a non-capture group
  ^                 : match beginning of line
  (?!.*\bLecture\b) : assert the line does not contain 'Lecture'
  .*\r?\n           : match the line
)                   : end non-capture group
*                   : execute the non-capture group 0+ times
|                   : or
^\r?\n              : match an empty line
|                   : or
^.*\r?\n            : match a line
(?!                 : begin a negative lookahead
  [\s\S]*           : match 0+ characters, including line terminators
  \bLecture\b       : match 'Lecture'
)                   : end negative lookahead
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...