Как извлечь строку по шаблону с помощью GREP, REGEX или PERL
У меня есть файл, который выглядит примерно так:
<table name="content_analyzer" primary-key="id">
<type="global" />
</table>
<table name="content_analyzer2" primary-key="id">
<type="global" />
</table>
<table name="content_analyzer_items" primary-key="id">
<type="global" />
</table>
Мне нужно извлечь что-нибудь в кавычках, которые следуют за "name=", т. е. content_analyzer , content_analyzer2 и content_analyzer_items.
Я делаю это на коробке Linux, поэтому решение с использованием sed, perl, grep или bash отлично.
8 ответов:
так как вам нужно сопоставить контент, не включая его в результат (должен матч
name="но это не часть желаемого результата) некоторых форм требуется сопоставление нулевой ширины или захват группы. Это можно сделать легко с помощью следующих инструментов:Perl
С Perl вы можете использовать
nвариант для того чтобы закрепить петлей линию линией и напечатать содержимое группы захвата, если оно соответствует:perl -ne 'print "\n" if /name="(.*?)"/' filenameGNU grep
если вы есть улучшенная версия grep, например GNU grep, у вас может быть элемент доступен. Этот параметр включает Perl-подобное регулярное выражение, позволяет использовать
\Kкоторый является стенографическим взглядом. Он будет сброшен положение спички, поэтому что-нибудь перед ним нулевая ширина.grep -Po 'name="\K.*?(?=")' filenameThe
oопция заставляет grep печатать только совпадающий текст, а не вся линия.Vim-Текстовый Редактор
другой способ-использовать текстовый редактор непосредственно. С Vim, одним из различными способами достижения этого было бы удаление строк без
name=а затем извлечь содержимое из полученных строк::v/name=/d :%s/\v.*name\="([^"]+)".*/
стандартный grep
если у вас нет доступа к этим инструментам, по какой-то причине, что-то подобное может быть достигнуто с помощью стандартной утилиты grep. Правда, без взгляда вокруг него потребуется некоторая очистка позже:
grep -o 'name="[^"]*"' filename
примечание о сохранении результаты
во всех командах выше результаты будут отправлены в
stdout. Это важно помнить, что вы всегда можете сохранить их, передавая по трубопроводу файл путем добавления:> resultдо конца команды.
Если вы используете Perl, загрузите модуль для анализа XML: XML:: Simple,XML:: Twig или XML:: LibXML. Не изобретайте заново колесо.
для этой цели следует использовать парсер HTML, а не регулярные выражения. Программа Perl, которая использует
HTML::TreeBuilder:программа
#!/usr/bin/env perl use strict; use warnings; use HTML::TreeBuilder; my $tree = HTML::TreeBuilder->new_from_file( \*DATA ); my @elements = $tree->look_down( sub { defined $_[0]->attr('name') } ); for (@elements) { print $_->attr('name'), "\n"; } __DATA__ <table name="content_analyzer" primary-key="id"> <type="global" /> </table> <table name="content_analyzer2" primary-key="id"> <type="global" /> </table> <table name="content_analyzer_items" primary-key="id"> <type="global" /> </table>выход
content_analyzer content_analyzer2 content_analyzer_items
вот решение с использованием HTML tidy & xmlstarlet:
htmlstr=' <table name="content_analyzer" primary-key="id"> <type="global" /> </table> <table name="content_analyzer2" primary-key="id"> <type="global" /> </table> <table name="content_analyzer_items" primary-key="id"> <type="global" /> </table> ' echo "$htmlstr" | tidy -q -c -wrap 0 -numeric -asxml -utf8 --merge-divs yes --merge-spans yes 2>/dev/null | sed '/type="global"/d' | xmlstarlet sel -N x="http://www.w3.org/1999/xhtml" -T -t -m "//x:table" -v '@name' -n
ой, команда sed должна предшествовать аккуратной команде, конечно:
echo "$htmlstr" | sed '/type="global"/d' | tidy -q -c -wrap 0 -numeric -asxml -utf8 --merge-divs yes --merge-spans yes 2>/dev/null | xmlstarlet sel -N x="http://www.w3.org/1999/xhtml" -T -t -m "//x:table" -v '@name' -n
если структура вашего xml (или текста в целом) фиксирована, самый простой способ-использовать
cut. Для вашего конкретного случая:echo '<table name="content_analyzer" primary-key="id"> <type="global" /> </table> <table name="content_analyzer2" primary-key="id"> <type="global" /> </table> <table name="content_analyzer_items" primary-key="id"> <type="global" /> </table>' | grep name= | cut -f2 -d '"'
Comments