使用另一个文件中的值更改文件 - Bash 脚本

使用另一个文件中的值更改文件 - Bash 脚本

我正在尝试编写一个脚本,该脚本采用两个文件作为参数,并使用 .csv 文件中的值更改 .svg 文件。 Csv 文件由具有两个值的行组成;编号,颜色。我需要在 svg 文件中找到 id 并将颜色添加到 id 匹配的行我不知道我的问题是否是 sed 部分,因为在更改中引入变量时它会变得复杂,或者脚本从根本上来说是有缺陷的。

id=($(cut -f1 -d, $2))
colour=($(cut -f2 -d, $2))
file=$1
name=$(basename -s .svg $1)
name1=$(echo "$name""1")
cat $2 | while IFS=, read id colour; do 
sed -i "s/id=\"'"$id"'\"/id=\"'"$id"'\" style=\"fill:\"'"$colour"'\";\"/" "$1"
done

当我使用它时,sed -i 's/id="ca"/id="ca" style="fill:red;"/' data.svg这会更改文件,但是当我用“$id”或“$id”更改“ca”时,它不起作用。

我也尝试过这个:

cat $2 | while IFS=, read id colour; do 
sed -i 's/id='"$id"'/id='"$id"' style="fill:red;"/' "$1"
done

我得到的结果是这样的:<g id= style="fill:red;""hi"> 预期的结果是这样的:
<g id="hi" style="fill:red;">

当我将 $color 放入 sed 时,sed -i 's/id='"$id"'/id='"$id"' style="fill:'"$colour"';"/' "$1"像这样,我得到:<g id= style="fill:;""hi">

答案1

  1. 您不需要将 CSV 读入变量,您可以直接循环 CSV:
cat data.csv | while IFS=, read id colour; do # something with $id and $colour
  1. 这样做var=$(echo text)有点多余——你应该直接使用var="text"

  2. 我不确定你所说的 struct 是什么意思[ "grep -E..." ],但这基本上是测试测试中的字符串是否不为空,这不是因为你只是在其中放入了一些文本。

编写 bash 脚本时,最好从命令行 (*) 依次测试每个表达式并查看其行为是否符合您的预期 - 这样可以消除很多意外情况。编写一个完整的脚本然后运行它,而没有大量关于如何写好脚本的经验,可能是搬起石头砸自己的脚的好方法。我有多年编写 bash 脚本的经验,在将事情写成脚本之前,我仍然在命令行上尝试并失败了很多次。当您运行脚本时,运行它以-x启用命令跟踪将非常有帮助。

我猜想您无法让替换工作的主要原因是 SVG 文件使用双引号 ( ") 作为 ID 属性,而不是像表达式中那样使用单引号sed

在 shell 脚本中构造sed表达式时,处理所有转义通常很烦人。如果可能的话,我通常喜欢sed完全不引用表达式,这就是我经常使用非斜杠的正则表达式分隔符的原因之一(正如我们接下来会看到的)。您需要将id和的值放入表达式coloursed,同时正确识别 SVG 属性的引用。可能有用的一件事是这样的:

sed -i "s,id=\"$id\",id=\"$id\" style=\"fill:$colour;\"," "$1"

在这里,我们只是在表达式周围使用双引号 - 这允许我们嵌入变量 - 并且只是转义双引号以进行匹配,以防止它们终止 shell 字符串。

另一种选择是由sed具有不同引用规则的多个字符串组成表达式:

sed -i 's,id="'"$id"'",id="'"$id"'" style="fill:'"$colour"';",' "$1"

在这里,我们将所有静态文本放在单引号中,然后终止单引号并打开双引号字符串来解析变量。这是可行的,因为单引号字符串和双引号字符串之间没有空格,并且只要没有空格,Bash 就会将所有这些作为单个参数传递给sed.但显然这有点令人困惑,所以我更喜欢第一种风格。

我们可以做的另一件事是使用捕获组来避免多次sed键入:id="$id"

sed -i "s,\(id=\"$id\"\),\1 style=\"fill:$colour;\"," "$1"

\(捕获\)匹配的内容,并将\1其放回到替换的字符串中。 *) 如果您在 MS-Windows 中编写过脚本,您可能知道那里的令人沮丧的情况,命令行(无论是 CMD 还是 powershell)的行为与在脚本中运行相同的命令不同,而且通常不太明显。这是不是Unix 脚本 shell(例如 Bash)中的情况。

相关内容