【发布时间】:2016-06-29 10:03:04
【问题描述】:
我需要帮助来理解 sed、bash 和 while 循环的一个奇怪问题。
我的数据如下所示:
-文件 1- CSV
account,hostnames,status,ipaddress,port,user,pass
-文件 2- XML - 这是一个帐户下的两个条目的示例记录集
<accountname="account">
<cname="fqdn or simple name goes here">
<field="hostname">ahostname or ipv4 goes here</field>
<protocol>aprotocol</protocol>
<field="port">aportnumber</field>
<field="username">ausername</field>
<field="password">apassword</field>
</cname>
<cname="fqdn or simple name goes here">
<field="hostname">ahostname or ipv4 goes here</field>
<protocol>aprotocol</protocol>
<field="port">aportnumber</field>
<field="username">ausername</field>
<field="password">apassword</field>
</cname>
</accountname>
到目前为止,我可以在从 File1 到 File2 的各个帐户持有人之间添加记录。但是,如果我需要删除不再存在的记录,它不会有效地工作,因为它会擦除来自不同帐户的其他记录,即它不会在匹配的帐户名之间删除。
我在 bash 程序中使用 while 循环从文件 1 导入文件 2:
-Bash Program excerpts-
//Read File in to F//
cat File 2 | while read F
do
//extract fields from F into variables
_vmname="$(echo $F |grep 'cname'| sed 's/<cname="//g' |sed 's/.\{2\}$//g')"
_account="$(echo $F | grep 'accountname' | sed 's/accountname="//g' |sed 's/.\{2\}$//g')"
// I then compare my File1 and look for stale records that are still in File2
if grep "$_vmname" File1 ;then
continue
else
// if not matched, delete between the respective accountname
sed -i '/'"$_account"'/,/<\/accountname>/ {/'"$_vmname"'/,/<\/cname>/d}' File2
如果我手动声明 _vmname 和 _account 并运行
sed -i '/'"$_account"'/,/<\/accountname>/ {/'"$_vmname"'/,/<\/cname>/d}' File2
它从 File2 中删除过时的记录。当我让我的 bash 脚本运行时,它没有。
我认为我有三个问题:
- 在循环中读取 _vmname 和 _account name 的变量会导致多次读取。任何更好的方法都值得赞赏。
- 我认为用于匹配这两种模式然后删除的 sed 语句在 while 循环中不会像我想要的那样工作。
- 我的思维链可能有逻辑问题。
任何指针,请不要使用 awk、perl、lxml 或 python。
谢谢!
【问题讨论】:
-
你没有尝试插入一些
echo行来跟踪循环内一些变量的值吗?您是否尝试过手动运行擦除sed命令并检查它是否有效? -
股票建议:不要使用像
sed这样的面向行的工具来操作 XML 数据。请改用xsltproc和xmlstarlet等支持XML 的工具。 -
是的,在循环外运行 sed 语句可以正常工作,并且使用 echo 进行跟踪表明我的 _vmname 和 _account 字段正在被读取并为每条记录解析三次。
-
尝试将 while 循环更改为重定向而不是管道,
while read F; do ... done < File2。另外,您在条件中的 grep 是指grep -q吗?也许你想要这样的东西:grep -q "$v_name" File1 && continue -
您的 XML 不是 XML。