2013-12-04 5 views
2

Допустим, у меня есть файл с линиями, как этотGrep - регулярное выражение - матч до определенного слова

abcefghijklxyz 
abcefghijkl 

Я хочу, чтобы получить только строки между abc и концом строки. Конец строки может быть определен как обычный конец строки или строка xyz.

Мой вопрос

Как я могу получить только найденную строку, используя grep и регулярные выражения? Например, ожидаемый выход для двух линий, показанных выше, будет

efghijkl 
efghijkl 

Я не хочу, начальный и конечный маркеры.

То, что я пытался до сих пор

grep -oh "abc.*xyz" 

Я использую Ubuntu 13.04 и Bash оболочки.

+0

Downvoter, пожалуйста, дайте мне знать, что не так с этим вопросом. – thefourtheye

ответ

6

эта линия отсекает ведущий abc и заканчиваяxyz (если был), и дает вам необходимую информацию:

grep -oP '^abc\K.*?(?=xyz$|$)' 

с вашим примером:

kent$ echo "abcefghijklxyz 
abcefghijkl"|grep -oP '^abc\K.*?(?=xyz$|$)' 
efghijkl 
efghijkl 

еще один пример с xyz в середине текста:

kent$ echo "abcefghijklxyz 
abcefghijkl 
abcfffffxyzbbbxyz 
abcffffxyzbbb"|grep -oP '^abc\K.*?(?=xyz$|$)' 
efghijkl 
efghijkl 
fffffxyzbbb 
ffffxyzbbb 
+0

+1 Я не знаю, кто это проигнорировал. Я проверяю, работает ли это для моих фактических данных. – thefourtheye

+4

downvote приветствуется, только если с объяснением, чтобы люди могли узнать, почему решение недостаточно хорошо (или плохо). Downvoter, вы бы опубликовали короткий комментарий? – Kent

+0

Для чего нужен '\ K'? – Alfe

1

Используйте look-behind так:

$ grep -Po '(?<=abc)[^x]*' file 
efghijkl 
efghijkl 

Он не получает все после abc и, пока он находит x.


на основе Kent's answer (не копировать, но для полноты), вы можете grep все в пределах abc и xyz (или конец строки):

$ grep -Po '(?<=abc).*(?=xyz|$)' file 
efghijklxyz 
efghijkl 
+0

Я тоже не хочу 'xyz'. Может ли это также быть разделено с регулярным выражением? – thefourtheye

+0

Можете ли вы проверить обновленный код, @thefourtheye? – fedorqui

+0

Да, @Alfe, как я говорю в своем ответе. – fedorqui

2

Использование СЭД:

sed -n '/abc/{s/.*abc\(.*\)/\1/;s/xyz.*//;p}' input 

Производит:

efghijkl 
efghijkl 
0

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

awk '/^abc/{sub(/^abc/,x);sub(/xyz.*$/,x)}1' file 
efghijkl 
efghijkl 

xyz.*$ представляют все от xyz до конца строки.

Смежные вопросы