Извлечение совпадающих слов с помощью grep на Cygwin

Я использую Cygwin, поэтому я просматриваю информацию PREIX regex.

Я пытаюсь выполнить поиск в файле xml для строки, и я продолжаю получать всю строку, но не могу сузить результаты до нескольких символов, которые я ищу.

Файл (file1) имеет много экземпляров:

<!ENTITY abc123456 SYSTEM "../blah/abc123456.xyz" NDATA xyz> <!ENTITY abc123457 SYSTEM "../blah/abc123457.xyz" NDATA xyz> <!ENTITY abc123458 SYSTEM "../blah/abc123458.xyz" NDATA xyz> 

Результаты grep отображают всю строку, но я пытаюсь сузить результаты до:

 abc123456.xyz abc123457.xyz abc123458.xyz 

Следующие успешно дают мне строки:

 grep -E abc[[:digit:]] file1 grep abc[0-9] file1 grep "abc[[:digit:]]" file1 

Поскольку то, что я ищу, не находится в начале или конце строки, ^ и $, похоже, не являются полезными. Не знаете, как привязать то, что я ищу. Я пробовал немало других вариантов использования grep без успеха.

Должны быть более элегантные решения (возможно, grep -P – один?), Но вы можете использовать sed для симуляции grep и получения строк, которые вы хотите, в случаях, когда простого grep -o недостаточно:

 sed -nr 's/.*SYSTEM "..\/blah\/([^"]*).*/\1/p' 

Это будет в основном соответствовать всей строке, а затем полностью заменить ее подстрокой, которую вы искали.

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

GNU grep, который является версией, включенной в Cygwin, имеет возможность отображать только ту часть строки, которая соответствует шаблону: -o .

 grep -o 'abc[0-9][^"]*' file1 

Вы можете добавить \b в начале шаблона, чтобы соответствовать только пробелу или пунктуации, т. /fooabc123.xyz Избегать сопоставления /fooabc123.xyz . Если вы хотите точно соответствовать после / или " , символ препинания будет включен в вывод, вы можете избежать этого с помощью утверждения lookbehind, которое доступно в синтаксисе regex Perl.

 grep -o -P '(?<=[/"])abc[0-9][^"]*' file1