链接到原始问题:bash script extract XML data into column format,现在进行修改和解释 - >
这行代码中的某些内容不正确,我相信它与substr部分有关,那是因为我没有完全理解,并且想学习如何更好地理解它。是的,我查看了文档,但没有完全点击。一些例子和一个答案真的很有帮助。
awk -F'[<>]' 'BEGIN{a["STKPR"]="Prod";a["STKSVBLKU"]="Prod";a["STKSVBLOCK"]="Prod";a["STKSVBLK2"]="Test";} /Name/{name=$3; type=a[substr(name,length(name))]; if (length(type)==0) type="Test";} /SessionHost/+/Host/{print type, name, $3;}'|sort -u
这一点:
type=a[substr(name,length(name))]; if (length(type)==0) type="Test";
这是xml格式,每个位都是包含主机名和IP的每个主机的块。
<?xml version="1.0"?>
<Connection>
<ConnectionType>Putty</ConnectionType>
<CreatedBy>Someone</CreatedBy>
<CreationDateTime>2014-10-27T11:53:32.0157492-04:00</CreationDateTime>
<CredentialConnectionID>9F3C3BCF-068A-4927-B996-CA52154CAE3B</CredentialConnectionID>
<Description>Red Hat Enterprise Linux 5 (64-bit)</Description>
<Events>
<OpenCommentPrompt>true</OpenCommentPrompt>
<WarnIfAlreadyOpened>true</WarnIfAlreadyOpened>
</Events>
<Group>PATH/TO/GROUP/NAME</Group>
<ID>f2007f03-3b33-47d3-8335-ffd84ccc0e6b</ID>
<MetaInformation />
<Name>STKSPRDAPP01111</Name>
<OpenEmbedded>true</OpenEmbedded>
<PinEmbeddedMode>False</PinEmbeddedMode>
<Putty>
<AlwaysAskForPassword>true</AlwaysAskForPassword>
<Domain>DOMAIN</Domain>
<FontSize>12</FontSize>
<Host>10.0.0.111</Host>
<Port>22</Port>
<PortFowardingArray />
<TelnetEncoding>IBM437</TelnetEncoding>
</Putty>
<Stamp>85407098-127d-4d3c-b7fa-8f174cb1e3bd</Stamp>
<SubMode>2</SubMode>
<TemplateName>SSH-PerUserCreds</TemplateName>
</Connection>
我想要做的是与上面引用的链接类似。但在这里我要匹配 - &gt;
BEGIN{a["STKPR"]="Prod";a["STKSVBLKU"]="Prod";a["STKSVBLOCK"]="Prod";a["STKSVBLK2"]="Test";
以及所有其余的作为测试。最好阅读上一篇文章,以帮助使这一点更容易理解。谢谢。
答案 0 :(得分:2)
由于此处的密钥长度不同,因此substr
方法不是最佳方法。尝试:
awk -F'[<>]' '/Name/{n=$3;t="Test"; if(n ~ /^STKPR/) t="Prod"; if (n ~/^STKSVBLKU/) t="Prod"; if (n ~/^STKSVBLOCK/) t="Prod"} /SessionHost/+/Host/{print t, n, $3;}' sample.xml |sort -u
Test STKSPRDAPP01111 10.0.0.111
在这种情况下,由t
表示的类型是根据一系列if
语句设置的。从上面的代码中可以看出:
t="Test"
if (n ~ /^STKPR/) t="Prod"
if (n ~ /^STKSVBLKU/) t="Prod"
if (n ~ /^STKSVBLOCK/) t="Prod"
通过设置t="Test"
,Test
成为默认值:除非另一个语句匹配,否则类型将为Test
。如果以下语句查看以主机名开头的字符串,并且如果匹配,则将类型t
设置为新值。 (当正则表达式以^
开头时,这意味着后面的内容必须在字符串的开头匹配。)
由于以上三个if
语句都是针对Prod
类型的,因此如果您愿意,可以将其中三个重新排列为:
t="Test"
if (n ~ /^STK(PR|SVBLKU|SVBLOCK)/) t="Prod"
(金属化:固定不匹配的括号括号)
答案 1 :(得分:1)
substr
部分生成一个包含字符串最后一个字符的字符串。这是因为从位于字符串末尾的位置name
开始采用字符串length(name)
的子字符串,并且因为substr
从1开始编制索引。
要匹配整个字符串,您可以使用变量name
,而不是使用substr
处理它。
/Name/ { name=$3; type=a[name]; if (length(type)==0) type="Test"; }