使用 bash 和 awk 编辑 xml,awk 不替换文本
Editing xml using bash and awk, awk don't replace text
我有一个配置文件,有新的版本代码,比如 SAD10A_BNA_1234_123456_110011,这个数字是写到 config.txt,这个数字我必须放在这个 [=22] 的 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="">
试试这个作为 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"
这定义了一个名为 new
的 awk
变量,它包含 NewNumber
.
的值
/Parameter1/ && NR==1
这会选择 (1) 包含 Parameter1
且 (2) 是文件第一行 (NR==1
) 的行。
sub(/Parameter1="[[:alnum:]_]*/, "Parameter1=\""new)
这会进行替换。注意正则表达式的三个变化:
通过使用 [:alnum:]
代替 [A-Z0-9]
,正则表达式现在对于 Unicode 字体是安全的。
下划线字符已添加到允许的字符中。
在[[:alnum:]_]
之后添加了一个*
,这样可以匹配零个或多个字符。以前,它只匹配一个。
另请注意,替换文本现在使用变量 new
。这避免了 shell-引用问题,并且如果 NewNumber
包含 awk
- 活动字符也更安全。
同时更改 parameter1
和 parameter2
如果 parameter1
和 parameter2
出现在输入文件的第二行,以下代码会更改它们:
$ 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="">
我有一个配置文件,有新的版本代码,比如 SAD10A_BNA_1234_123456_110011,这个数字是写到 config.txt,这个数字我必须放在这个 [=22] 的 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="">
试试这个作为 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"
这定义了一个名为
new
的awk
变量,它包含NewNumber
. 的值
/Parameter1/ && NR==1
这会选择 (1) 包含
Parameter1
且 (2) 是文件第一行 (NR==1
) 的行。sub(/Parameter1="[[:alnum:]_]*/, "Parameter1=\""new)
这会进行替换。注意正则表达式的三个变化:
通过使用
[:alnum:]
代替[A-Z0-9]
,正则表达式现在对于 Unicode 字体是安全的。下划线字符已添加到允许的字符中。
在
[[:alnum:]_]
之后添加了一个*
,这样可以匹配零个或多个字符。以前,它只匹配一个。
另请注意,替换文本现在使用变量
new
。这避免了 shell-引用问题,并且如果NewNumber
包含awk
- 活动字符也更安全。
同时更改 parameter1
和 parameter2
如果 parameter1
和 parameter2
出现在输入文件的第二行,以下代码会更改它们:
$ 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="">