72

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

  <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

这个命令可能是什么?

4

5 回答 5

113

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
于 2013-05-21T16:51:43.927 回答
99

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

做这项工作。

' ' 里面的部分的解释

  • s - 告诉 sed 替换
  • / - 要搜索的正则表达式字符串的开始
  • [^"]* - 任何不是 " 的字符,任意次数。(匹配参数名称=
  • “——只是一个
  • ([^"]*) - () 中的任何内容都将被保存以供以后参考使用。\ 在那里,因此括号不被视为要搜索的字符。[^"]* 的含义与上述相同。(例如匹配RemoteHost )
  • .* - 任意字符,任意次数。(匹配“ access="readWrite"> /parameter
  • / - 搜索正则表达式的结尾,以及替换字符串的开头。
  • \1 - 引用我们在上面括号中找到的那个字符串。
  • / 替代字符串的结尾。

基本上是 s/search for this/replace with this/,但我们告诉他用我们之前找到的一部分替换整行。

于 2013-05-21T16:47:04.023 回答
45

你想要awk

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

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

PortMappingEnabled
PortMappingLeaseDuration
RemoteHost
ExternalPort
ExternalPortEndRange
InternalPort
PortMappingProtocol
InternalClient
PortMappingDescription
于 2013-05-21T16:46:34.620 回答
19

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

如果输入发生变化,并且在名称参数之前,您将获得换行符而不是空格,它会在某天失败,产生意想不到的结果。

如果您确实确定您的输入将始终以这种方式格式化,您可以使用cut. 它比sed和更快awk更快:

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

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

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

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

于 2013-05-21T17:06:57.373 回答
9

解释如何使用cut

cat yourxmlfile | cut -d'"' -f2

它将基于" d分隔符"剪切"文件中的所有行,并将占用您想要的第二字段

于 2018-06-13T08:41:51.807 回答