我正在尝试写一个Bash脚本来改变一个XML文件名和这个XML文件中超过500个不同文件夹的内容。社区的一个成员帮助了这个美妙脚本的the first iteration。
我更喜欢使用sed
命令来执行这个带有Bash脚本的进程,而不是使用xmlstarlet
,因为我不想在这个虚拟机上安装它。
下面是要修改的文件的示例:
/var/opt/FTPserver/users/MainUsers/junk/VFS/junk2.xml
^^^^ ^^^^^
字符串
用junk2.xml
包含一行:
<url>file://home/FTPserver/Customer/junk2/</url>
^^^^^
型
我想将文件重命名为以下名称:
/var/opt/FTPserver/users/MainUsers/junk/VFS/treasure.xml
^^^^ ^^^^^^^^
型
新命名的treasure.xml
包含修改后的行:
<url>file://home/FTPserver/Customer/treasure/</url>
^^^^^^^^
型
作为我的测试示例,customerlogin.csv
以逗号分隔,列oldStr = junk
、列midStr = junk2
和列newStr = treasure
。
CSV示例
junk,junk2,treasure
help,helpful,helping
old,middle,new
dog,dog,cat
dir='/var/opt/FTPserver/users/MainUsers/'
while IFS=, read -r oldStr midStr newStr; do
oldFile="$dir/$oldStr/VFS/${midStr}.xml"
newFile="$dir/$oldStr/VFS/${newStr}.xml"
if [[ -f "$oldFile" ]] && [[ ! -f "$newFile" ]];
then
sed "s:/$midStr/:/$newStr/:" "$oldFile" > "$newFile" &&
rm -f "$oldFile"
fi
done < customerlogin.csv
的字符串
当我运行脚本时,如果所有三列都是不同的名称,它将完全按照我所希望的方式工作。但是,如果列A(oldStr
)和列B(midStr
)碰巧具有相同的值,如(dog)&(dog),则XML文件名将更改为cat,但XML内容将保持不变,仍为dog。
如果(oldStr
)值等于(midStr
),则收到的结果
/var/opt/FTPserver/users/MainUsers/dog/VFS/cat.xml
^^^ ^^^
<url>file://home/FTPserver/Customer/dog</url>
^^^
型
如果(oldStr
)值不等于(midStr
),则收到结果
/var/opt/FTPserver/users/MainUsers/help/VFS/helpful.xml
^^^^ ^^^^^^^
<url>file://home/FTPserver/Customer/helping</url>
^^^^^^^
型
我不知道是什么原因造成的,我将如何解决它。
1条答案
按热度按时间ergxz8rk1#
您的正则表达式正在寻找
/dog/
,但您的XML文件却有/dog<
(请注意,在/dog
和</url>
之间没有/
):字符串
因此,无论
$oldStr
==$midStr
是否匹配,regexp都不会匹配(因此,如您所示,在文件中helpful
变为helping
是不正确的)。在上一个问题中,当尝试匹配
/junk
/时,您的输入文件看起来像这样(注意/junk
和</url>
之间的/
):型
因此,如果您当前的XML文件现在遵循相同的格式,那么该文件将如下所示(注意,
/
现在位于/dog
和</url>
之间):型
因此
/dog/
将存在,匹配regexp,并被替换。如果在
<
之前可能有/
,但总是有<
,在您想要修改的文件中,请更改以下内容:型
为此,使用GNU或BSD sed for
-E
:型