当字母出现时,为什么awk sub会改变我的输入?

时间:2017-04-07 22:52:41

标签: awk

我有一个XML文件,结构如下:

    <diskTypes>
        <diskType typeName="data001" sectors="5859356127" sectorSize="512"/>
        <diskType typeName="data002" sectors="23437457375" sectorSize="512"/>
        <diskType typeName="data003" sectors="46882764767" sectorSize="512"/>
    </diskTypes>

我想使用awk在第一行末尾添加注释,其中包含序列号。我想要的输出是:

    <diskTypes>
        <diskType typeName="data001" sectors="5859356127" sectorSize="512"/> <!--serial=051161dc00000009-->
        <diskType typeName="data002" sectors="23437457375" sectorSize="512"/>
        <diskType typeName="data003" sectors="46882764767" sectorSize="512"/>
    </diskTypes>

尝试完成这项工作我已经提出了这个awk命令:

/usr/bin/awk '/<diskType typeName=".*\/>$/ && n == 0 { sub(/<diskType typeName=".*/, $1 " " $2 " " $3 " " $4 " <!--serial="051161dc00000009"-->"); ++n } { print }' Media1.cfgx > editedVol0.xml

然而我最终得到的结果是:

    <diskTypes>
        <diskType typeName="data001" sectors="5859356127" sectorSize="512"/> <!--serial=51161-->
        <diskType typeName="data002" sectors="23437457375" sectorSize="512"/>
        <diskType typeName="data003" sectors="46882764767" sectorSize="512"/>
    </diskTypes>

我不明白awk将 051161dc00000009 序列注释的输入转换为 51161

文件中的结果

如果我的输入不包含任何这样的字母:

05116100000009 instead of 051161dc00000009

我的结果越来越近了,看起来像这样:

...  <!--serial=5116100000009--> ...

但即便如此,由于某种原因,awk正在切断第一个0。

有人可以帮我解决这个awk声明,并帮助我理解为什么我在处理由所有数字组成的序列时丢失0,以及为什么我在51161之后丢失了所有涉及任何字母的内容?< / p>

2 个答案:

答案 0 :(得分:1)

说实话,我不明白你的代码是在尝试什么,但是只需将你发布的输入转换为你发布的输出

$ awk '/<diskTypes>/{c=0} {print $0 (++c==2 ? " <!--serial=051161dc00000009-->" : "")}' file
<diskTypes>
    <diskType typeName="data001" sectors="5859356127" sectorSize="512"/> <!--serial=051161dc00000009-->
    <diskType typeName="data002" sectors="23437457375" sectorSize="512"/>
    <diskType typeName="data003" sectors="46882764767" sectorSize="512"/>
</diskTypes>

答案 1 :(得分:0)

经过一系列的测试后,我发现通过在数字末尾的空格后添加“”,它告诉awk将前一个文本/数字块视为字符串。为了确保这一点,我还需要首先删除字符串周围的引号。

所以最终的工作命令如下所示:

/usr/bin/awk '/<diskType typeName=".*\/>$/ && n == 0 { sub(/<diskType typeName=".*/, $1 " " $2 " " $3 " " $4 " <!--serial\=051161dc00000009 ""-->"""); ++n } { print }' Media1.cfgx > editedVol0.xml

重要的部分是删除序列号附近的引号和添加空格,然后在序列号后面引用2。这就是告诉awk直接在“”之前的项目是一个字符串,无论awk可能猜到它是什么。

 <!--serial\=051161dc00000009 ""-->""")

感谢Lawson Hanson从1997年开始回答这个问题! https://groups.google.com/forum/#!topic/comp.lang.awk/uS9LL99-agQ