Bash使用特殊字符在两个字符串之间获取文本

时间:2017-08-27 11:08:39

标签: bash awk sed grep

我正忙着为Domoticz编写脚本,可以通过gamertag查询读取我的Xbox One。但我需要从一些特殊字符中提取。找不到任何解决方案,我可以使用,GREP,TR,AWK,SED等。最好是一行代码。

这是字符串:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
    <session-factory>
        <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
        <property name="dialect">Netsis.Framework.Persister.Hibernate.Dialect.NMsSql2008Dialect, Netsis.Framework.Persister</property>
        <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
        <property name="connection.connection_string">Data Source=localhost;Initial Catalog=CRM;Persist Security Info=True;User ID=user;Password=pass</property>
        <property name="proxyfactory.factory_class">Netsis.Framework.Persister.Hibernate.Proxy.PropertyReaderProxyFactoryFactory,Netsis.Framework.Persister</property>
        <property name="show_sql">True</property>
        <property name="format_sql">True</property>
        <property name="adonet.batch_size">30</property>  
    </session-factory>
</hibernate-configuration>

这是一行代码,我只需要{&#34; type&#34;:&#34; XboxOne till}]},这样我只有我的控制台信息。但这些是特殊字符,我搜索高低,但找不到任何解决方案。

这是我最终会遇到的字符串。

{"type":"XboxOne","titles":[{"id":714681658,"name":"Home","placement":"Background","state":"Active","lastModified":"2017-08-26T19:56:33.9199136Z"},{"id":252034287,"activity":{"richPresence":"In Main Menu"},"name":"The Elder Scrolls V: Skyrim Special Edition","placement":"Background","state":"Active","lastModified":"2017-08-26T19:56:33.9199136Z"},{"id":1693425033,"name":"Spotify Music - for Test","placement":"Full","state":"Active","lastModified":"2017-08-26T19:56:33.9199136Z"}]},{"type":"WindowsOneCore","titles":[{"id":328178078,"name":"Xbox App","placement":"Full","state":"Active","lastModified":"2017-08-26T19:53:40.7273986Z"}]}]}

非常感谢任何帮助!

谢谢,

3 个答案:

答案 0 :(得分:3)

一个班轮

cat filename | grep -oP '\{"type":"XboxOne".*?(?=,{"type")' 

简要说明:
(?=,{"type"):在找到模式,{"type"后停止匹配 .*?:进行延迟匹配并捕获所有内容,直到,{"type"的第一个匹配(例如,如果你的json中有多个对象)

答案 1 :(得分:1)

可以使用这样的gawk脚本来完成:

<强> script.awk

BEGIN { RS="}]}";
        tgt="{\"type\":\"XboxOne"
      }

      { p=index($0, tgt); 
        if(p) printf("%s%s\n\n", substr($0, p ), RS)
      }

像这样使用:awk -f script.awk yourfile

<强>解释 这个想法是使用静态字符串而不是regexp来最小化转义特殊字符。这是这样做的:

  • RS记录分隔符设置为常量字符串}]}每个记录在这样的情况下结束,而不是在行结束
  • tgt也是一个常量字符串,用作index函数的参数,我们只需要转义双引号

如果找到tgt(即p>0),我们会打印从p到记录结束的子字符串(这是文本,但不包括}]}我们另外打印出RS

您可以将脚本放入awk的单行参数中(我添加了必要的;),但为了清楚起见,我将其放入多行脚本中。

答案 2 :(得分:0)

这是一个sed解决方案,

sed 's/,{"type".*$/,/g' file

该命令会将匹配正则表达式,"type".*$的字符串替换为满足您请求的,