提取与unix中的模式匹配的所有子字符串

时间:2018-05-24 05:17:53

标签: unix sed

我在文本文件中有一个字符串,如下所示。

messageBodyPart.setFileName("logo.png"); 

字符串是连续的,未格式化为正确的xml

我必须从标签中提取所有值

我使用了以下脚本

<sample:Recipients><sample:user name="11111111" guid="8fa4fbaabf904a16ad65449bd7adcba1"/><sample:user name="22222222" guid="f74ebd3310834601a2c22a5dde33c02a"/><sample:user name="33333333" guid="5fcd2e7775cb42ecbed5ac5dd85e1ca6"/></sample:Recipients>

但我只得到最后一个值grep -o "<sample:Recipients>.*</sample:Recipients>" "sample.txt"|sed -n 's/.*\([0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]\).*/\1/p' 。如何从所有用户标签中提取值?

3 个答案:

答案 0 :(得分:2)

关注单awk可能会对您有所帮助。

awk '
{
  while(match($0,/sample:user name=\"[^"]*[0-9]+/)){
    print substr($0,RSTART+18,RLENGTH-18);
    $0=substr($0,RSTART+RLENGTH+1)}
}'  Input_file

答案 1 :(得分:1)

您可以使用以下快速而脏的grep命令来实现目标:

$ grep -E 'sample:Recipients>|<sample:user' file | grep -oP '(?<=name=")[^"]*'

<强> INPUT:

$ 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的行,第二个将使用{{1}从名为name的属性中选择值具有正面观察力的正则表达式perl

使用(?<=name=")[^"]*的另一个快速而肮脏的解决方案:

sed

<强>说明:

您使用$ grep -E 'sample:Recipients>|<sample:user' file | sed -n '/name="/s/.*name="\([^"]*\)".*/\1/gp' ******1 *******2 *******3 并仅在匹配模式sed时处理行,然后通过对名称值的反向引用替换整行:name=(属性值)

良好的解决方案:

而不是grepping或使用\1只需使用xml解析器来分析你的xml输出:

sed

这是最安全的工作方式,请注意$ 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>&#xa;</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 :(得分:0)

您可以试试这个awk脚本“:

awk -v RS='<[a-z:]+|/>' -v FS='[a-z]+=' '{gsub("[\" ]",""); print $2,$3}'

记录分隔符RS设置为在<...\>之间获取所有内容。字段separtor设置为捕获符号=的左侧部分。

gsub命令摆脱了双引号和额外空格。

print语句显示名称和guid。如果您不需要guid,请删除,$3声明中的print