Grep: максимум слов до и после матча - PullRequest
3 голосов
/ 24 января 2012

Можно ли заставить grep показывать максимальное количество слов до и после матча?Например, учитывая строку

aaa bbb ccc ddd eee fff ggg hhh iii jjj kkk lll mmm nnn ooo ppp qqq rrr sss

, я бы хотел, чтобы grep не возвращал всю строку, а только, скажем, 3 слова до и после совпадения.например, при поиске 'iii' результат будет

fff ggg hhh iii jjj kkk lll

Я пробовал это, но результат не возвращается:

grep -o '\w{0, 20}MY_SEARCH\w{0, 20}' *

Ответы [ 3 ]

2 голосов
/ 24 января 2012
string='aaa bbb ccc ddd eee fff ggg hhh iii jjj kkk lll mmm nnn ooo ppp qqq rrr sss'

echo $string | grep -oP '(([a-zA-Z]+) ){0,3}iii( ([a-zA-Z]+)){0,3}'

Если я правильно понял ваш вопрос, это следует делать, когда максимальное количество слов с каждой стороны равно 3.

0 голосов
/ 07 марта 2014
grep -E -o '.{0, 3}iii.{0, 3}'

это выведет это

hhh iii jjj

если вы хотите удалить 'iii', вы также можете передать sed

grep -E -o '.{0,3}iii.{0,3}' | sed 's/iii//g'

это выведет это

hhh jjj
0 голосов
/ 24 января 2012

Я попытался преобразовать пробелы в символы новой строки, а затем использовать опции -A и -B, а затем преобразовать \ n в пробел.

$ echo "aaa bbb ccc ddd eee fff ggg hhh iii jjj kkk lll mmm nnn ooo ppp qqq rrr sss" | tr ' ' '\n' | grep -A3 -B3 "iii" | tr '\n' ' '

op => fff ggg hhh iii jjj kkk lll

Я знаю, что это грубый подход, но нужно проверить, есть ли другой лучший вариант.

Я написал небольшой сценарий оболочки с этой логикой для обработки нескольких файлов. Проверьте это

#!/bin/bash

for i in `find . -name "*.txt"`
do
    FNAME=$i
    MATCHED=""
    if grep "iii" $i > /dev/null 2>&1
    then
        MATCHED=`cat $i | tr ' ' '\n' | grep -A3 -B3 "iii" | tr '\n' ' '`
    fi

    if [ "$MATCHED" != "" ]
    then
        echo "$FNAME|$MATCHED"
    fi
done    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...