Проблема пунктуации с использованием grep для получения n слов вокруг токена

Я пытаюсь обработать файл. Моя попытка не сработала. Входной файл описывает желаемый результат:

Входной файл:

Это токен, но когда встречается какая-либо пунктуация, он останавливает извлечение.

Я хочу получить n слов вокруг определенного токена, что означает n слов перед токеном и n слов после токена. Нет шаблона исправления, как указано в некоторых других решениях.

Пожалуйста помоги. Спасибо.

Используемая команда:

$ grep -io -E '(\w+ ){0,5}\b(token)\b( \w+){0,5}' grepping-n-words-around-token 

Вывод:

 This is a token n words around a specific token meaning n words before the token and n words after the token 

Желаемый результат:

 This is a token, but when any punctuation is n words around a specific token, meaning n words before the meaning n words before the token and n words after the and n words after the token. There is no fix pattern 

  • Grep один вкладыш для удаления блоков случайного текста
  • Строки списка, которые состоят из одного негласного символа
  • Список точных строк в файле
  • grep на одну строку перед матчем плюс матч
  • Grep первые 50 строк файлов для шаблона
  • получение списка всех строчных слов в файле
  • grep: отображать имя файла один раз, затем отображать контекст с номерами строк
  • Разделить с помощью sed
  • One Solution collect form web for “Проблема пунктуации с использованием grep для получения n слов вокруг токена”

    У вас не может быть GNU grep -o вывести один и тот же текст (например, ваше meaning n words before the or and n words after the ). Вы можете сделать это с помощью pcregrep хотя используя -o<n> где n является n й группой захвата и pcregrep то, что сопоставляется в операторе внешнего вида (который не продвигает курсор для следующего совпадения):

     $ pcregrep -o0 -o2 '(\w+\W+){0,5}token(?=((\W+\w+){0,5}))' file This is a token, but when any punctuation is n words around a specific token, meaning n words before the meaning n words before the token and n words after the and n words after the token. There is no fix pattern 

    -o0 – весь текст соответствует, -o1 – это то, что соответствует (....) внутри оператора (?=(here)) .

    Обратите внимание, что на входе, например:

     6 5 4 3 2 1 token token 1 2 3 4 5 6 

    это дало бы:

     5 4 3 2 1 token token 1 2 3 4 token 1 2 3 4 5 

    потому что он начинает искать второе совпадение сразу после первого токена , так что только находит 0 слов перед вторым token .

     $ echo 6 5 4 3 2 1 token token 1 2 3 4 5 6 | pcregrep -o1 '(?=((\w+\W+){0,5}token(\W+\w+){0,5}))\w*' 5 4 3 2 1 token token 1 2 3 4 4 3 2 1 token token 1 2 3 4 5 3 2 1 token token 1 2 3 4 5 2 1 token token 1 2 3 4 5 1 token token 1 2 3 4 5 token token 1 2 3 4 5 token 1 2 3 4 5 

    Вероятно, это не так, как вы хотите (даже если каждый из них «токен» предшествует и сопровождается до 5 слов).

    Чтобы получить строку для каждого появления «токена» с до 5 слов с обеих сторон, я не думаю, что вы делаете это легко с помощью pcregrep .

    Вам нужно будет записать положение каждого слова «токена», а затем сопоставить up-to-5-words<that-position>"token"up-to-5-words the up-to-5-words<that-position>"token"up-to-5-words для каждой из этих позиций.

    Что-то вроде:

     $ echo 6 5 4 3 2 1 token token 1 2 3 4 5 6 | perl -lne ' my @positions; push @positions, $-[0] while /\btoken\b/g; for $o (@positions) { print $& if /(\w+\W+){0,5}(?<=^.{$o})token(\W+\w+){0,5}/ }' 5 4 3 2 1 token token 1 2 3 4 4 3 2 1 token token 1 2 3 4 5 

    Или для уточнения, какой токен подбирается в каждом случае:

     $ echo 6 5 4 3 2 1 token token 1 2 3 4 5 6 | perl -lne ' my @positions; push @positions, $-[0] while /\btoken\b/g; for $o (@positions) { print "$1<token>$3" if /((\w+\W+){0,5})(?<=^.{$o})token((\W+\w+){0,5})/ }' 5 4 3 2 1 <token> token 1 2 3 4 4 3 2 1 token <token> 1 2 3 4 5 

    (Я ожидаю, что это может быть упрощено / оптимизировано).

    Linux и Unix - лучшая ОС в мире.