如何使用sed提取子字符串

时间:2013-05-21 16:40:28

标签: linux shell ubuntu xml-parsing sed

我有一个包含以下行的文件:

  <parameter name="PortMappingEnabled" access="readWrite" type="xsd:boolean"></parameter>
  <parameter name="PortMappingLeaseDuration" access="readWrite" activeNotify="canDeny" type="xsd:unsignedInt"></parameter>
  <parameter name="RemoteHost" access="readWrite"></parameter>
  <parameter name="ExternalPort" access="readWrite" type="xsd:unsignedInt"></parameter>
  <parameter name="ExternalPortEndRange" access="readWrite" type="xsd:unsignedInt"></parameter>
  <parameter name="InternalPort" access="readWrite" type="xsd:unsignedInt"></parameter>
  <parameter name="PortMappingProtocol" access="readWrite"></parameter>
  <parameter name="InternalClient" access="readWrite"></parameter>
  <parameter name="PortMappingDescription" access="readWrite"></parameter>

我想对此文件执行命令以仅提取以下输出中显示的参数名称:

$sedcommand file.txt
PortMappingEnabled
PortMappingLeaseDuration
RemoteHost
ExternalPort
ExternalPortEndRange
InternalPort
PortMappingProtocol
InternalClient
PortMappingDescription

这个命令可能是什么?

5 个答案:

答案 0 :(得分:79)

grep 诞生于提取事物:

grep -Po 'name="\K[^"]*'

使用您的数据进行测试:

kent$  echo '<parameter name="PortMappingEnabled" access="readWrite" type="xsd:boolean"></parameter>
  <parameter name="PortMappingLeaseDuration" access="readWrite" activeNotify="canDeny" type="xsd:unsignedInt"></parameter>
  <parameter name="RemoteHost" access="readWrite"></parameter>
  <parameter name="ExternalPort" access="readWrite" type="xsd:unsignedInt"></parameter>
  <parameter name="ExternalPortEndRange" access="readWrite" type="xsd:unsignedInt"></parameter>
  <parameter name="InternalPort" access="readWrite" type="xsd:unsignedInt"></parameter>
  <parameter name="PortMappingProtocol" access="readWrite"></parameter>
  <parameter name="InternalClient" access="readWrite"></parameter>
  <parameter name="PortMappingDescription" access="readWrite"></parameter>
'|grep -Po 'name="\K[^"]*'
PortMappingEnabled
PortMappingLeaseDuration
RemoteHost
ExternalPort
ExternalPortEndRange
InternalPort
PortMappingProtocol
InternalClient
PortMappingDescription

答案 1 :(得分:51)

sed 's/[^"]*"\([^"]*\).*/\1/'

完成这项工作。

答案 2 :(得分:32)

你想要awk

这将是一个快速而肮脏的黑客:

awk -F "\"" '{print $2}' /tmp/file.txt

PortMappingEnabled
PortMappingLeaseDuration
RemoteHost
ExternalPort
ExternalPortEndRange
InternalPort
PortMappingProtocol
InternalClient
PortMappingDescription

答案 3 :(得分:15)

您不应使用sed或awk等工具解析XML。这很容易出错。

如果输入更改,并且在name参数之前,您将获得换行符而不是空格,它将在某一天失败,从而产生意外结果。

如果您确定,您的输入将始终以这种方式格式化,则可以使用cut。 它比sedawk

更快
cut -d'"' -f2 < input.txt

最好首先解析它,并仅提取参数名称属性:

xpath -q -e //@name input.txt | cut -d'"' -f2

要了解有关xpath的更多信息,请参阅本教程:http://www.w3schools.com/xpath/

答案 4 :(得分:4)

说明如何使用cut

cat yourxmlfile | cut -d'"' -f2

它会削减&#39;文件中的所有行都基于&#34; d elimiter,将采用 2 nd f ield,这就是你想要的。