Вы можете использовать следующие быстрые и грязные grep
команды для достижения вашей цели:
$ grep -E 'sample:Recipients>|<sample:user' file | grep -oP '(?<=name=")[^"]*'
ВХОД:
$ cat file
abc
abc1
<sample:Recipients>
<sample:user name="******1" guid="8fa4fbaabf904a16ad65449bd7adcba1"/>
<sample:user name="*******2" guid="f74ebd3310834601a2c22a5dde33c02a"/>
<sample:user name="*******3" guid="5fcd2e7775cb42ecbed5ac5dd85e1ca6"/>
</sample:Recipients>
abc2
abc
ВЫХОД:
$ grep -E 'sample:Recipients>|<sample:user' file | grep -oP '(?<=name=")[^"]*'
******1
*******2
*******3
Пояснения:
Первый grep
извлечет строки, содержащие XML, который вы хотите изолировать из вашего входного файла,второй выберет значения из атрибутов с именем name
, используя perl
regex (?<=name=")[^"]*
с положительным взглядом сзади.
Другое быстрое и грязное решение с использованием sed
:
$ grep -E 'sample:Recipients>|<sample:user' file | sed -n '/name="/s/.*name="\([^"]*\)".*/\1/gp'
******1
*******2
*******3
Пояснения:
Вы используете sed
и обрабатываете линии только при сопоставлениишаблон name=
затем вы заменяете всю строку обратной ссылкой на значение имени: \1
(значение атрибута)
ХОРОШЕЕ РЕШЕНИЕ:
вместоgrepping или используя sed
просто используйте анализатор xml для анализа вашего вывода xml:
$ cat extract_name.xsl
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" omit-xml-declation="yes" indent="no"/>
<xsl:template match="/">
<xsl:for-each select="/*/*/@name">
<xsl:value-of select="."/><xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
$ xsltproc extract_name.xsl <(grep -E 'sample:Recipients>|<sample:user' file) 2>/dev/null
******1
*******2
*******3
Это самый безопасный способ работы, обратите внимание, что 2>/dev/null
используется для игнорирования предупреждения пространства именпотому что образец пространства имен не определен правильно.