I'm trying edit an xml file which has the following values
我正在尝试编辑一个具有以下值的xml文件
<item type="4" key="Port 1 Desc" value_type="1">
<item type="4" key="Port 1 InOctets" value_type="3">
<item type="4" key="Port 1 OutOctets" value_type="3">
I would like to eliminate the space and replce it with - my desired output would be like this:
我想消除这个空间,然后用-我想要的输出是这样的:
<item type="4" key="Port-1-Desc" value_type="1">
<item type="4" key="Port-1-InOctets" value_type="3">
<item type="4" key="Port-1-OutOctets" value_type="3">
Please keep in mind that number 1 is variable, and my xml file has port 2, 3 , 24 ..etc.
请记住,1是变量,我的xml文件有端口2、3、24等。
Thank you
谢谢你!
4 个解决方案
#1
1
We prefer to use xml tool directly to handle xml file, such as in @Charles Duffy's reply.
Here is the way which only for this file, using awk.
这里是使用awk的方法。
awk '{gsub(/ /,"-",$4)}1' FS=\" OFS=\" file
<item type="4" key="Port-1-Desc" value_type="1">
<item type="4" key="Port-1-InOctets" value_type="3">
<item type="4" key="Port-1-OutOctets" value_type="3">
Explaination
-
gsub(regexp, replacement [, target])
Search target for all of the longest, leftmost, nonoverlapping matching substrings it can find and replace them with replacement. The ‘g’ in gsub() stands for “global,” which means replace everywhere. - gsub(regexp, replace [, target])搜索目标,搜索它可以找到的所有最长、最左、最不重叠的匹配子字符串,并用替换替换它们。gsub()中的“g”代表“global”,意思是到处都可以替换。
-
FS=\" OFS=\"
field separators - FS = \“OFS = \”字段分隔符
-
1
same as print - 1打印一样
#2
2
Using sed
使用sed
sed "{$(echo 's/ /-/3;'{,})}" file
$ cat file
<item type="4" key="Port 1 Desc" value_type="1">
<item type="4" key="Port 1 InOctets" value_type="3">
<item type="4" key="Port 1 OutOctets" value_type="3">
$ sed "{$(echo 's/ /-/3;'{,})}" file
<item type="4" key="Port-1-Desc" value_type="1">
<item type="4" key="Port-1-InOctets" value_type="3">
<item type="4" key="Port-1-OutOctets" value_type="3">
#3
2
This approach requires XMLStarlet.
这种方法需要XMLStarlet。
It has the advantage of working as long as your XML is valid, rather than relying on the line-by-line formatting being exact, as many of the other answers here do.
只要XML是有效的,它就可以工作,而不是像这里的许多其他答案那样依赖逐行格式。
elem=
xmlstarlet pyx | while IFS='' read -r line; do
if [[ $line = '('* ]]; then
elem=${line:1}
printf '%s\n' "$line"
elif [[ $line = Akey* && $elem = item ]]; then
value=${line#*" "}
value=${line//" "/_}
printf 'Akey %s\n' "$value"
else
printf '%s\n' "$line"
fi
done | xmlstarlet depyx
#4
1
Here is the single line solution using sed
这是使用sed的单行解决方案
sed 's/Port \([0-9]*\) /Port-\1-/g' filename
Note that, \1
is the remembered pattern.
注意,\1是记住的模式。
aman@apollo:~$ cat t
<item type="4" key="Port 1 Desc" value_type="1">
<item type="4" key="Port 1 InOctets" value_type="3">
<item type="4" key="Port 1 OutOctets" value_type="3">
aman@apollo:~$ sed 's/Port \([0-9]*\) /Port-\1-/g' t
<item type="4" key="Port-1-Desc" value_type="1">
<item type="4" key="Port-1-InOctets" value_type="3">
<item type="4" key="Port-1-OutOctets" value_type="3">
#1
1
We prefer to use xml tool directly to handle xml file, such as in @Charles Duffy's reply.
Here is the way which only for this file, using awk.
这里是使用awk的方法。
awk '{gsub(/ /,"-",$4)}1' FS=\" OFS=\" file
<item type="4" key="Port-1-Desc" value_type="1">
<item type="4" key="Port-1-InOctets" value_type="3">
<item type="4" key="Port-1-OutOctets" value_type="3">
Explaination
-
gsub(regexp, replacement [, target])
Search target for all of the longest, leftmost, nonoverlapping matching substrings it can find and replace them with replacement. The ‘g’ in gsub() stands for “global,” which means replace everywhere. - gsub(regexp, replace [, target])搜索目标,搜索它可以找到的所有最长、最左、最不重叠的匹配子字符串,并用替换替换它们。gsub()中的“g”代表“global”,意思是到处都可以替换。
-
FS=\" OFS=\"
field separators - FS = \“OFS = \”字段分隔符
-
1
same as print - 1打印一样
#2
2
Using sed
使用sed
sed "{$(echo 's/ /-/3;'{,})}" file
$ cat file
<item type="4" key="Port 1 Desc" value_type="1">
<item type="4" key="Port 1 InOctets" value_type="3">
<item type="4" key="Port 1 OutOctets" value_type="3">
$ sed "{$(echo 's/ /-/3;'{,})}" file
<item type="4" key="Port-1-Desc" value_type="1">
<item type="4" key="Port-1-InOctets" value_type="3">
<item type="4" key="Port-1-OutOctets" value_type="3">
#3
2
This approach requires XMLStarlet.
这种方法需要XMLStarlet。
It has the advantage of working as long as your XML is valid, rather than relying on the line-by-line formatting being exact, as many of the other answers here do.
只要XML是有效的,它就可以工作,而不是像这里的许多其他答案那样依赖逐行格式。
elem=
xmlstarlet pyx | while IFS='' read -r line; do
if [[ $line = '('* ]]; then
elem=${line:1}
printf '%s\n' "$line"
elif [[ $line = Akey* && $elem = item ]]; then
value=${line#*" "}
value=${line//" "/_}
printf 'Akey %s\n' "$value"
else
printf '%s\n' "$line"
fi
done | xmlstarlet depyx
#4
1
Here is the single line solution using sed
这是使用sed的单行解决方案
sed 's/Port \([0-9]*\) /Port-\1-/g' filename
Note that, \1
is the remembered pattern.
注意,\1是记住的模式。
aman@apollo:~$ cat t
<item type="4" key="Port 1 Desc" value_type="1">
<item type="4" key="Port 1 InOctets" value_type="3">
<item type="4" key="Port 1 OutOctets" value_type="3">
aman@apollo:~$ sed 's/Port \([0-9]*\) /Port-\1-/g' t
<item type="4" key="Port-1-Desc" value_type="1">
<item type="4" key="Port-1-InOctets" value_type="3">
<item type="4" key="Port-1-OutOctets" value_type="3">