Проблема пунктуации с использованием 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
  • Как искать текст в файле, игнорируя новые строки?
  • Проверьте, имеют ли файлы в определенном каталоге надлежащее расширение?
  • Awk / bash Keep line containg только 3 поля
  • Является ли -r обязательным для grep?
  • 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 - лучшая ОС в мире.