如何在带有变量的文件中的某个字符串后插入文本
How to insert text after a certain string in a file with variables
我有这些变量:
file_path="/home/dir/file.xml"
string="<host mac='0A:00:DD:D2:00:02' name='vfp-20vr' ip='10.10.1.122'/>"
这是file.xml
的内容
<network>
<name>br-ext</name>
<forward mode='route'/>
<bridge name='br-ext' stp='on' delay='0'/>
<mac address='52:54:00:9f:a0:00'/>
<ip address='10.10.1.11' netmask='255.255.255.0'>
<dhcp>
<host mac='0A:AA:FF:C1:A1:EE' name='vsrxa-1' ip='10.10.1.21'/>
<host mac='0A:AA:FF:C1:A2:EE' name='vsrxa-2' ip='10.10.1.22'/>
<host mac='0A:AA:FF:C1:B1:EE' name='vsrxb-1' ip='10.10.1.23'/>
<host mac='0A:AA:FF:C1:B2:EE' name='vsrxb-2' ip='10.10.1.24'/>
<host mac='0A:AA:FF:C1:C1:EE' name='vsrxc-1' ip='10.10.1.25'/>
<host mac='0A:AA:FF:C1:C2:EE' name='vsrxc-2' ip='10.10.1.26'/>
<host mac='0A:AA:FF:C1:D1:EE' name='vsrxd-1' ip='10.10.1.27'/>
<host mac='0A:AA:FF:C1:D2:EE' name='vsrxd-2' ip='10.10.1.28'/>
</dhcp>
</ip>
</network>
我想在 <dhcp>
标志之后添加 $string
,如下所示:
...
<dhcp>
<host mac='0A:00:DD:D2:00:02' name='vfp-20vr' ip='10.10.1.122'/>
<host mac='0A:AA:FF:C1:A1:EE' name='vsrxa-1' ip='10.10.1.21'/>
...
我尝试在我的 bash 脚本中使用 sed "/\dhcp\/a $string $file_path"
但没有成功...
有谁知道我怎样才能做到这一点?
你还差得远:
sed -i "/<dhcp>/a \ \ \ \ \ \ ${string}" "${file_path}"
-i
更改输入文件
/<dhcp>/
至 select 仅 dhcp
打开标签
- (
\
) * 6 缩进 string
内容
结果:
<network>
<name>br-ext</name>
<forward mode='route'/>
<bridge name='br-ext' stp='on' delay='0'/>
<mac address='52:54:00:9f:a0:00'/>
<ip address='10.10.1.11' netmask='255.255.255.0'>
<dhcp>
<host mac='0A:00:DD:D2:00:02' name='vfp-20vr' ip='10.10.1.122'/>
<host mac='0A:AA:FF:C1:A1:EE' name='vsrxa-1' ip='10.10.1.21'/>
<host mac='0A:AA:FF:C1:A2:EE' name='vsrxa-2' ip='10.10.1.22'/>
<host mac='0A:AA:FF:C1:B1:EE' name='vsrxb-1' ip='10.10.1.23'/>
<host mac='0A:AA:FF:C1:B2:EE' name='vsrxb-2' ip='10.10.1.24'/>
<host mac='0A:AA:FF:C1:C1:EE' name='vsrxc-1' ip='10.10.1.25'/>
<host mac='0A:AA:FF:C1:C2:EE' name='vsrxc-2' ip='10.10.1.26'/>
<host mac='0A:AA:FF:C1:D1:EE' name='vsrxd-1' ip='10.10.1.27'/>
<host mac='0A:AA:FF:C1:D2:EE' name='vsrxd-2' ip='10.10.1.28'/>
</dhcp>
</ip>
</network>
试试这个
#! /bin/bash
file_path="$HOME/test.xml"
content="<host>b</host>"
c=$(echo $content | sed 's/\//\\//g')
sed "/<\/dhcp>/ s/.*/${c}\n&/" $file_path
使用sed
$ sed "/<dhcp>/{p;s|\( \+\).*| $string|;}" file
<network>
<name>br-ext</name>
<forward mode='route'/>
<bridge name='br-ext' stp='on' delay='0'/>
<mac address='52:54:00:9f:a0:00'/>
<ip address='10.10.1.11' netmask='255.255.255.0'>
<dhcp>
<host mac='0A:00:DD:D2:00:02' name='vfp-20vr' ip='10.10.1.122'/>
<host mac='0A:AA:FF:C1:A1:EE' name='vsrxa-1' ip='10.10.1.21'/>
<host mac='0A:AA:FF:C1:A2:EE' name='vsrxa-2' ip='10.10.1.22'/>
<host mac='0A:AA:FF:C1:B1:EE' name='vsrxb-1' ip='10.10.1.23'/>
<host mac='0A:AA:FF:C1:B2:EE' name='vsrxb-2' ip='10.10.1.24'/>
<host mac='0A:AA:FF:C1:C1:EE' name='vsrxc-1' ip='10.10.1.25'/>
<host mac='0A:AA:FF:C1:C2:EE' name='vsrxc-2' ip='10.10.1.26'/>
<host mac='0A:AA:FF:C1:D1:EE' name='vsrxd-1' ip='10.10.1.27'/>
<host mac='0A:AA:FF:C1:D2:EE' name='vsrxd-2' ip='10.10.1.28'/>
</dhcp>
</ip>
</network>
使用 bash
和 sed
的 a
(追加)命令:
sed '/^[[:blank:]]*<dhcp>[[:blank:]]*$/a'$'\\n'"$string" "$file_path"
strings=" STRING1...\n STRING2...\n ...\n"
match="<dhcp>"
awk -v m="$match" -v s="$strings" '{ print; if( == m) printf s }' input_file
<network>
<name>br-ext</name>
<forward mode='route'/>
<bridge name='br-ext' stp='on' delay='0'/>
<mac address='52:54:00:9f:a0:00'/>
<ip address='10.10.1.11' netmask='255.255.255.0'>
<dhcp>
STRING1...
STRING2...
...
<host mac='0A:AA:FF:C1:A1:EE' name='vsrxa-1' ip='10.10.1.21'/>
<host mac='0A:AA:FF:C1:A2:EE' name='vsrxa-2' ip='10.10.1.22'/>
<host mac='0A:AA:FF:C1:B1:EE' name='vsrxb-1' ip='10.10.1.23'/>
<host mac='0A:AA:FF:C1:B2:EE' name='vsrxb-2' ip='10.10.1.24'/>
<host mac='0A:AA:FF:C1:C1:EE' name='vsrxc-1' ip='10.10.1.25'/>
<host mac='0A:AA:FF:C1:C2:EE' name='vsrxc-2' ip='10.10.1.26'/>
<host mac='0A:AA:FF:C1:D1:EE' name='vsrxd-1' ip='10.10.1.27'/>
<host mac='0A:AA:FF:C1:D2:EE' name='vsrxd-2' ip='10.10.1.28'/>
</dhcp>
</ip>
</network>
您可以使用模式来匹配 <dhcp>
部分并捕获前导 spaces。
然后追加下一个字符串,用完整匹配替换最后一个模式,后跟换行符和反向引用以保持相同的缩进。
从那时起,您可以使用自己的缩进来扩展它。
sed "/^\([[:space:]]*\)<dhcp>/{N;s##&\n $string#}" "$file_path"
说明
/^\([[:space:]]*\)<dhcp>/
Natch 字符串的开始,捕获可选的 spaces 并匹配 <dhcp>
N
将下一行附加到模式 space
s
替换
##
最后匹配的模式(我把替换的分隔符改成了#
)
&\n
替换为完整匹配项、换行符和对包含缩进的第 1 组的反向引用并添加您自己的缩进
输出
<network>
<name>br-ext</name>
<forward mode='route'/>
<bridge name='br-ext' stp='on' delay='0'/>
<mac address='52:54:00:9f:a0:00'/>
<ip address='10.10.1.11' netmask='255.255.255.0'>
<dhcp>
<host mac='0A:00:DD:D2:00:02' name='vfp-20vr' ip='10.10.1.122'/>
<host mac='0A:AA:FF:C1:A1:EE' name='vsrxa-1' ip='10.10.1.21'/>
<host mac='0A:AA:FF:C1:A2:EE' name='vsrxa-2' ip='10.10.1.22'/>
<host mac='0A:AA:FF:C1:B1:EE' name='vsrxb-1' ip='10.10.1.23'/>
<host mac='0A:AA:FF:C1:B2:EE' name='vsrxb-2' ip='10.10.1.24'/>
<host mac='0A:AA:FF:C1:C1:EE' name='vsrxc-1' ip='10.10.1.25'/>
<host mac='0A:AA:FF:C1:C2:EE' name='vsrxc-2' ip='10.10.1.26'/>
<host mac='0A:AA:FF:C1:D1:EE' name='vsrxd-1' ip='10.10.1.27'/>
<host mac='0A:AA:FF:C1:D2:EE' name='vsrxd-2' ip='10.10.1.28'/>
</dhcp>
</ip>
</network>
对于类似的任务,我使用 xmlstarlet
。显然,您从 xml 来源获得了 $string
。因此,您可以使用 xmlstarlet
来获取 mac、name 和 ip 值。让我们假设你得到了它们。然后,您可以像这样将新主机添加到 $file_path
中:
xmlstarlet edit --inplace \
--insert /network/ip/dhcp/host[1] --type elem --name new_host --value "" \
--insert //new_host --type attr --name mac --value $new_host_mac \
--insert //new_host --type attr --name name --value $new_host_name \
--insert //new_host --type attr --name ip --value $new_host_ip \
--rename //new_host --value host \
$file_path
我有这些变量:
file_path="/home/dir/file.xml"
string="<host mac='0A:00:DD:D2:00:02' name='vfp-20vr' ip='10.10.1.122'/>"
这是file.xml
<network>
<name>br-ext</name>
<forward mode='route'/>
<bridge name='br-ext' stp='on' delay='0'/>
<mac address='52:54:00:9f:a0:00'/>
<ip address='10.10.1.11' netmask='255.255.255.0'>
<dhcp>
<host mac='0A:AA:FF:C1:A1:EE' name='vsrxa-1' ip='10.10.1.21'/>
<host mac='0A:AA:FF:C1:A2:EE' name='vsrxa-2' ip='10.10.1.22'/>
<host mac='0A:AA:FF:C1:B1:EE' name='vsrxb-1' ip='10.10.1.23'/>
<host mac='0A:AA:FF:C1:B2:EE' name='vsrxb-2' ip='10.10.1.24'/>
<host mac='0A:AA:FF:C1:C1:EE' name='vsrxc-1' ip='10.10.1.25'/>
<host mac='0A:AA:FF:C1:C2:EE' name='vsrxc-2' ip='10.10.1.26'/>
<host mac='0A:AA:FF:C1:D1:EE' name='vsrxd-1' ip='10.10.1.27'/>
<host mac='0A:AA:FF:C1:D2:EE' name='vsrxd-2' ip='10.10.1.28'/>
</dhcp>
</ip>
</network>
我想在 <dhcp>
标志之后添加 $string
,如下所示:
...
<dhcp>
<host mac='0A:00:DD:D2:00:02' name='vfp-20vr' ip='10.10.1.122'/>
<host mac='0A:AA:FF:C1:A1:EE' name='vsrxa-1' ip='10.10.1.21'/>
...
我尝试在我的 bash 脚本中使用 sed "/\dhcp\/a $string $file_path"
但没有成功...
有谁知道我怎样才能做到这一点?
你还差得远:
sed -i "/<dhcp>/a \ \ \ \ \ \ ${string}" "${file_path}"
-i
更改输入文件/<dhcp>/
至 select 仅dhcp
打开标签- (
\
) * 6 缩进string
内容
结果:
<network>
<name>br-ext</name>
<forward mode='route'/>
<bridge name='br-ext' stp='on' delay='0'/>
<mac address='52:54:00:9f:a0:00'/>
<ip address='10.10.1.11' netmask='255.255.255.0'>
<dhcp>
<host mac='0A:00:DD:D2:00:02' name='vfp-20vr' ip='10.10.1.122'/>
<host mac='0A:AA:FF:C1:A1:EE' name='vsrxa-1' ip='10.10.1.21'/>
<host mac='0A:AA:FF:C1:A2:EE' name='vsrxa-2' ip='10.10.1.22'/>
<host mac='0A:AA:FF:C1:B1:EE' name='vsrxb-1' ip='10.10.1.23'/>
<host mac='0A:AA:FF:C1:B2:EE' name='vsrxb-2' ip='10.10.1.24'/>
<host mac='0A:AA:FF:C1:C1:EE' name='vsrxc-1' ip='10.10.1.25'/>
<host mac='0A:AA:FF:C1:C2:EE' name='vsrxc-2' ip='10.10.1.26'/>
<host mac='0A:AA:FF:C1:D1:EE' name='vsrxd-1' ip='10.10.1.27'/>
<host mac='0A:AA:FF:C1:D2:EE' name='vsrxd-2' ip='10.10.1.28'/>
</dhcp>
</ip>
</network>
试试这个
#! /bin/bash
file_path="$HOME/test.xml"
content="<host>b</host>"
c=$(echo $content | sed 's/\//\\//g')
sed "/<\/dhcp>/ s/.*/${c}\n&/" $file_path
使用sed
$ sed "/<dhcp>/{p;s|\( \+\).*| $string|;}" file
<network>
<name>br-ext</name>
<forward mode='route'/>
<bridge name='br-ext' stp='on' delay='0'/>
<mac address='52:54:00:9f:a0:00'/>
<ip address='10.10.1.11' netmask='255.255.255.0'>
<dhcp>
<host mac='0A:00:DD:D2:00:02' name='vfp-20vr' ip='10.10.1.122'/>
<host mac='0A:AA:FF:C1:A1:EE' name='vsrxa-1' ip='10.10.1.21'/>
<host mac='0A:AA:FF:C1:A2:EE' name='vsrxa-2' ip='10.10.1.22'/>
<host mac='0A:AA:FF:C1:B1:EE' name='vsrxb-1' ip='10.10.1.23'/>
<host mac='0A:AA:FF:C1:B2:EE' name='vsrxb-2' ip='10.10.1.24'/>
<host mac='0A:AA:FF:C1:C1:EE' name='vsrxc-1' ip='10.10.1.25'/>
<host mac='0A:AA:FF:C1:C2:EE' name='vsrxc-2' ip='10.10.1.26'/>
<host mac='0A:AA:FF:C1:D1:EE' name='vsrxd-1' ip='10.10.1.27'/>
<host mac='0A:AA:FF:C1:D2:EE' name='vsrxd-2' ip='10.10.1.28'/>
</dhcp>
</ip>
</network>
使用 bash
和 sed
的 a
(追加)命令:
sed '/^[[:blank:]]*<dhcp>[[:blank:]]*$/a'$'\\n'"$string" "$file_path"
strings=" STRING1...\n STRING2...\n ...\n"
match="<dhcp>"
awk -v m="$match" -v s="$strings" '{ print; if( == m) printf s }' input_file
<network>
<name>br-ext</name>
<forward mode='route'/>
<bridge name='br-ext' stp='on' delay='0'/>
<mac address='52:54:00:9f:a0:00'/>
<ip address='10.10.1.11' netmask='255.255.255.0'>
<dhcp>
STRING1...
STRING2...
...
<host mac='0A:AA:FF:C1:A1:EE' name='vsrxa-1' ip='10.10.1.21'/>
<host mac='0A:AA:FF:C1:A2:EE' name='vsrxa-2' ip='10.10.1.22'/>
<host mac='0A:AA:FF:C1:B1:EE' name='vsrxb-1' ip='10.10.1.23'/>
<host mac='0A:AA:FF:C1:B2:EE' name='vsrxb-2' ip='10.10.1.24'/>
<host mac='0A:AA:FF:C1:C1:EE' name='vsrxc-1' ip='10.10.1.25'/>
<host mac='0A:AA:FF:C1:C2:EE' name='vsrxc-2' ip='10.10.1.26'/>
<host mac='0A:AA:FF:C1:D1:EE' name='vsrxd-1' ip='10.10.1.27'/>
<host mac='0A:AA:FF:C1:D2:EE' name='vsrxd-2' ip='10.10.1.28'/>
</dhcp>
</ip>
</network>
您可以使用模式来匹配 <dhcp>
部分并捕获前导 spaces。
然后追加下一个字符串,用完整匹配替换最后一个模式,后跟换行符和反向引用以保持相同的缩进。
从那时起,您可以使用自己的缩进来扩展它。
sed "/^\([[:space:]]*\)<dhcp>/{N;s##&\n $string#}" "$file_path"
说明
/^\([[:space:]]*\)<dhcp>/
Natch 字符串的开始,捕获可选的 spaces 并匹配<dhcp>
N
将下一行附加到模式 spaces
替换##
最后匹配的模式(我把替换的分隔符改成了#
)&\n
替换为完整匹配项、换行符和对包含缩进的第 1 组的反向引用并添加您自己的缩进
输出
<network>
<name>br-ext</name>
<forward mode='route'/>
<bridge name='br-ext' stp='on' delay='0'/>
<mac address='52:54:00:9f:a0:00'/>
<ip address='10.10.1.11' netmask='255.255.255.0'>
<dhcp>
<host mac='0A:00:DD:D2:00:02' name='vfp-20vr' ip='10.10.1.122'/>
<host mac='0A:AA:FF:C1:A1:EE' name='vsrxa-1' ip='10.10.1.21'/>
<host mac='0A:AA:FF:C1:A2:EE' name='vsrxa-2' ip='10.10.1.22'/>
<host mac='0A:AA:FF:C1:B1:EE' name='vsrxb-1' ip='10.10.1.23'/>
<host mac='0A:AA:FF:C1:B2:EE' name='vsrxb-2' ip='10.10.1.24'/>
<host mac='0A:AA:FF:C1:C1:EE' name='vsrxc-1' ip='10.10.1.25'/>
<host mac='0A:AA:FF:C1:C2:EE' name='vsrxc-2' ip='10.10.1.26'/>
<host mac='0A:AA:FF:C1:D1:EE' name='vsrxd-1' ip='10.10.1.27'/>
<host mac='0A:AA:FF:C1:D2:EE' name='vsrxd-2' ip='10.10.1.28'/>
</dhcp>
</ip>
</network>
对于类似的任务,我使用 xmlstarlet
。显然,您从 xml 来源获得了 $string
。因此,您可以使用 xmlstarlet
来获取 mac、name 和 ip 值。让我们假设你得到了它们。然后,您可以像这样将新主机添加到 $file_path
中:
xmlstarlet edit --inplace \
--insert /network/ip/dhcp/host[1] --type elem --name new_host --value "" \
--insert //new_host --type attr --name mac --value $new_host_mac \
--insert //new_host --type attr --name name --value $new_host_name \
--insert //new_host --type attr --name ip --value $new_host_ip \
--rename //new_host --value host \
$file_path