【发布时间】:2025-12-22 00:25:11
【问题描述】:
我需要这个 awk 命令将文本中第一个 XML 标记中的 ss:Width="252" 替换为 ss:Width="140" 并保留其余标记:
cat <<- EOF > text
<ss:Column ss:AutoFitWidth="1" ss:Width="252"/>
<ss:Column ss:AutoFitWidth="1" ss:Width="126"/>
<ss:Column ss:AutoFitWidth="1" ss:Width="126"/>
<ss:Column ss:AutoFitWidth="1" ss:Width="126"/>
<ss:Column ss:AutoFitWidth="1" ss:Width="126"/>
<ss:Column ss:AutoFitWidth="1" ss:Width="252"/>
<ss:Column ss:AutoFitWidth="1" ss:Width="126"/>
<ss:Column ss:AutoFitWidth="1" ss:Width="126"/>
<ss:Column ss:AutoFitWidth="1" ss:Width="189"/>
<ss:Column ss:AutoFitWidth="1" ss:Width="189"/>
<ss:Column ss:AutoFitWidth="1" ss:Width="252"/>
<ss:Column ss:AutoFitWidth="1" ss:Width="126"/>
<ss:Column ss:AutoFitWidth="1" ss:Width="126"/>
<ss:Column ss:AutoFitWidth="1" ss:Width="126"/>
<ss:Column ss:AutoFitWidth="1" ss:Width="126"/>
<ss:Column ss:AutoFitWidth="1" ss:Width="252"/>
EOF
awk '{c=++count[$0]} c==1 {sub(/ss:Width=\"[0-9]{1,4}\"/,"ss:Width=\"140\"")} {print}' text > newf
cat newf
相反,它替换了三个唯一匹配项中每一个的第一个实例中的表达式(总共三个替换,而我只想要一个。)
<ss:Column ss:AutoFitWidth="1" ss:Width="140"/>
<ss:Column ss:AutoFitWidth="1" ss:Width="140"/>
<ss:Column ss:AutoFitWidth="1" ss:Width="126"/>
<ss:Column ss:AutoFitWidth="1" ss:Width="126"/>
<ss:Column ss:AutoFitWidth="1" ss:Width="126"/>
<ss:Column ss:AutoFitWidth="1" ss:Width="252"/>
<ss:Column ss:AutoFitWidth="1" ss:Width="126"/>
<ss:Column ss:AutoFitWidth="1" ss:Width="126"/>
<ss:Column ss:AutoFitWidth="1" ss:Width="140"/>
<ss:Column ss:AutoFitWidth="1" ss:Width="189"/>
<ss:Column ss:AutoFitWidth="1" ss:Width="252"/>
<ss:Column ss:AutoFitWidth="1" ss:Width="126"/>
<ss:Column ss:AutoFitWidth="1" ss:Width="126"/>
<ss:Column ss:AutoFitWidth="1" ss:Width="126"/>
<ss:Column ss:AutoFitWidth="1" ss:Width="126"/>
<ss:Column ss:AutoFitWidth="1" ss:Width="252"/>
为什么会这样?增量器在我的 awk 命令中的行为如何?我希望它在 /ss:Width=\".*\"/ 的第一个合格匹配之后增加,但它似乎在找到所有 unique 匹配之前不会增加,然后忽略后续的非唯一只匹配。那正确吗?我试图强制计数器在 c == 1 块的末尾递增,如下所示:
awk '{c=++count[$0]} c==1 {sub(/ss:Width=\".*\"/,"ss:Width=\"140\"");c++} {print}' text > newf
但我得到相同的输出。我在 sed 中尝试这个任务没有任何运气,而且我宁愿在 awk 中完成它。我对理解这种 awk 语法特别感兴趣。
编辑:我通过将一个宽度属性更改为另一个随机数来测试这个理论。它也确实将那个替换为 140。因此,它仅限于所有匹配表达式的第一个实例,而不是第一个匹配表达式本身。
编辑:正如 Cody 指出的那样,我的正则表达式是贪婪的。我将 .* 更改为 [0-9]{1,4} 但是行为是相同的 - 它仍然只替换每个唯一匹配的第一个实例。我还将 XML 标记的宽度属性之一更改为第三个唯一编号,并更新了输出以说明我正在尝试修复的行为。
这是 AIX/ksh。
【问题讨论】: