【问题标题】:Editing xml using bash and awk, awk don't replace text使用 bash 和 awk 编辑 xml,awk 不替换文本
【发布时间】:2015-04-01 03:02:41
【问题描述】:

我有一个配置文件,带有新的版本代码,比如 SAD10A_BNA_1234_123456_110011,这个数字写入 config.txt,这个数字我必须放在这个 xml 文件的 4 个位置。

这是我的脚本:


#!/bin/bash

NewNumber=`cat config.txt`

echo $NewNumber
#This number is: PLE31Z_BNE_1111_1121211_313131

awk '/"Parameter1"/ && !done++{sub(/Parameter1="[A-Z0-9]"/, "Parameter1=\"'$NewNumber'\"")}1' OldFileWithVersionNumeber.xml > temp.xml && mv -f temp.xml Newfile$NewNumber.xml

#I know, I must write 3 awk, but first one doesn't work for now

cat targettext.xml | grep Parameter1

带有旧参数的 XML:


<OneSection Parameter1="SAD10A_BNA_1234_123456_110011" Parameter2="SAD10A_BNA_1234_123456_110011" Type="UWE-AD" date="05/01/2011">

 AND LOT OF VERY SIMILAR LINES
 AND TWO LINES WITH THE SAME NUMBER TO REPLACE

<xmlElement Name="" name="NameGB" version="_SAD10A_BNA_1234_123456_110011.xml" Unit="ERF" Blocks="1" params1="" params2="" Path1="/rom/" path2="" comp="" encrypted="">
<xmlElement KeyName="" name="NameGB" version="_SAD10A_BNA_1234_123456_110011.xml" Unit="ERFS" Blocks="1" params1="" params2="" Path1="/rom/" path2="" comp="" encrypted="">

【问题讨论】:

  • 在我看来!done++ 的目的是将匹配限制在第一行。对吗?
  • 最好避免使用旧的和过时的背部抽动,使用括号:NewNumber=$(cat config.txt)。也不要将cat 与可以读取数据本身的程序一起使用:grep Parameter1 targettext.xml
  • 不要在awk 表达式中使用变量。看这里:stackoverflow.com/questions/19075671/…

标签: xml bash shell awk sed


【解决方案1】:

试试这个awk 命令:

$ awk -v new="$NewNumber" '/Parameter1/ && NR==1{sub(/Parameter1="[[:alnum:]_]*/, "Parameter1=\""new)} 1' OldFileWithVersionNumeber.xml
<OneSection Parameter1="PLE31Z_BNE_1111_1121211_313131" Parameter2="SAD10A_BNA_1234_123456_110011" Type="UWE-AD" date="05/01/2011">

 AND LOT OF VERY SIMILAR LINES
 AND TWO LINES WITH THE SAME NUMBER TO REPLACE

<xmlElement Name="" name="NameGB" version="_SAD10A_BNA_1234_123456_110011.xml" Unit="ERF" Blocks="1" params1="" params2="" Path1="/rom/" path2="" comp="" encrypted="">
<xmlElement KeyName="" name="NameGB" version="_SAD10A_BNA_1234_123456_110011.xml" Unit="ERFS" Blocks="1" params1="" params2="" Path1="/rom/" path2="" comp="" encrypted="">

工作原理

  • -v new="$NewNumber"

    这定义了一个名为newawk 变量,其中包含NewNumber 的值。

  • /Parameter1/ &amp;&amp; NR==1

    这将选择 (1) 包含 Parameter1 并且 (2) 是文件的第一行 (NR==1) 的行。

  • sub(/Parameter1="[[:alnum:]_]*/, "Parameter1=\""new)

    这会进行替换。注意正则表达式的三处更改:

    • 通过使用[:alnum:] 代替[A-Z0-9],正则表达式现在对于Unicode 字体是安全的。

    • 下划线字符已添加到允许的字符中。

    • [[:alnum:]_] 之后添加*,以便可以匹配零个或多个字符。以前,它只匹配一个。

    另请注意,替换文本现在使用变量new。这样可以避免 shell 引用问题,并且如果 NewNumber 包含 awk-active 字符也会更安全。

同时更改 parameter1parameter2

如果parameter1parameter2 出现在输入文件的第二行,则以下代码会同时更改它们:

$ awk --posix -v new="$NewNumber" '/Parameter1/ && NR==2{sub(/Parameter1="[[:alnum:]_]*/, "Parameter1=\""new); sub(/Parameter2="[[:alnum:]_]*/, "Parameter2=\""new)} 1' OldFileWithVersionNumeber.xml

<OneSection Parameter1="PLE31Z_BNE_1111_1121211_313131" Parameter2="PLE31Z_BNE_1111_1121211_313131" Type="UWE-AD" date="05/01/2011">

 AND LOT OF VERY SIMILAR LINES
 AND TWO LINES WITH THE SAME NUMBER TO REPLACE

<xmlElement Name="" name="NameGB" version="_SAD10A_BNA_1234_123456_110011.xml" Unit="ERF" Blocks="1" params1="" params2="" Path1="/rom/" path2="" comp="" encrypted="">
<xmlElement KeyName="" name="NameGB" version="_SAD10A_BNA_1234_123456_110011.xml" Unit="ERFS" Blocks="1" params1="" params2="" Path1="/rom/" path2="" comp="" encrypted="">

【讨论】:

  • 感谢您的快速响应。不幸的是 You awk 不起作用 :( 我把 You awk 放到我的脚本中
  • “不起作用”是什么意思?如果您自己运行它,如答案所示,您会得到与我显示的相同的结果吗?这就是你想要的结果吗?或者,如果问题仅在 awk 行是脚本的一部分时发生,那么具体的症状是什么?
  • 如果我将此行添加到脚本中,这个awk不会替换parameter1,parameter1是一样的,parameter2也是。
  • 我发现错误,您输入了 awk NR==1,但这是我的第二行:) 并将数字更改为 2,现在它可以工作了 :) 我如何更改此 xml 中的参数 2?
  • @Dzions 非常好。我添加了一个新版本,如果这两个参数出现在文件的第二行,它会更改它们。
猜你喜欢
  • 2019-04-21
  • 2020-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-07
  • 2017-09-06
  • 1970-01-01
相关资源
最近更新 更多