使用sed用逗号分隔的csv一次编辑文件夹和xml文件

bxjv4tth  于 9个月前  发布在  其他
关注(0)|答案(1)|浏览(97)

我正在尝试写一个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>
                                    ^^^^^^^


我不知道是什么原因造成的,我将如何解决它。

ergxz8rk

ergxz8rk1#

您的正则表达式正在寻找/dog/,但您的XML文件却有/dog<(请注意,在/dog</url>之间没有/):

<url>file://home/FTPserver/Customer/dog</url>

字符串
因此,无论$oldStr == $midStr是否匹配,regexp都不会匹配(因此,如您所示,在文件中helpful变为helping是不正确的)。
在上一个问题中,当尝试匹配/junk/时,您的输入文件看起来像这样(注意/junk</url>之间的/):

<url>file://home/FTPserver/Customer/junk/</url>


因此,如果您当前的XML文件现在遵循相同的格式,那么该文件将如下所示(注意,/现在位于/dog</url>之间):

<url>file://home/FTPserver/Customer/dog/</url>


因此/dog/将存在,匹配regexp,并被替换。
如果在<之前可能有/,但总是有<,在您想要修改的文件中,请更改以下内容:

sed "s:/$midStr/:/$newStr/:"


为此,使用GNU或BSD sed for -E

sed -E "s:/$midStr(/?<):/$newStr\1:"

相关问题