我有一个美国地图的 SVG 文件,我想为其添加颜色。因为这会花费我很多时间,所以我想我可以使用 bash 脚本。我还有另一个文件,其中包含状态和属于它们的颜色。
SVG 文件:
<g id="hi">
<title>Hawaii</title>
<path class="state hi" d="m 233.08751,519.30948 ... z" id="HI" />
</g>
CSV 文件
HI, blue
我想要的是:
<g id="hi" style="fill:blue;">
<title>Hawaii</title>
<path class="state hi" d="m 233.08751,519.30948 ... z" id="HI" />
</g>
我以为我可以使用grep
orsed
但我真的不知道从哪里开始。
答案1
使用 bash 和 GNU sed:
while IFS=",$IFS" read id color
do
sed -i "s/g id=\"${id,,}\"/& style=\"fill:$color;\"/g" file.svg
done <file.csv
完成后,file.svg 看起来像:
<g id="hi" style="fill:blue;">
<title>Hawaii</title>
<path class="state hi" d="m 233.08751,519.30948 ... z" id="HI" />
</g>
怎么运行的
while IFS=",$IFS" read id color; do
这
while
通过读取变量id
和来启动循环color
。我们添加一个逗号,IFS
以便输入按逗号和空格分开。sed -i "s/g id=\"${id,,}\"/& style=\"fill:$color;\"/g" file.svg
这会对 file.svg 进行就地更新。这使用 bash 转换
id
为小写:${id,,}
。它查找该字符串g id="${id,,}"
并将其替换为g id="${id,,} style="fill:$color;"
。注意:
$id
和$color
直接替换为 sed 命令。你应该做这个除非您信任 file.csv 文件的来源。done <file.csv
这将结束
while
循环并指示它从 中读取file.csv
。
BSD (OSX)
如果您使用的是 BSD 系统,我们需要对 sed 命令稍作修改:
while IFS=",$IFS" read id color
do
sed -i "" "s/g id=\"${id,,}\"/& style=\"fill:$color;\"/g" file.svg
done <file.csv
答案2
使用 Perl 及其xsh :
perl {
open my $FH, '<', 'states.csv' or die $!;
$h->{lc $1} = "$2;" while <$FH> =~ /(.*),\s*(.*)/;
};
open map.xml ;
for //g set @style concat("fill:", xsh:lookup('h', @id));
save :b ;
答案3
使用 sed 两次:
</tmp/states.csv tr "[A-Z]" "[a-z]" | \
sed -n 's/^\([a-z]\{2\}\), \([^ ]*\)$/s@<g id="\1">@<g id="\1" style="fill:\2;">@/p' >/tmp/script.sed
sed -f /tmp/script.sed /tmp/source.svg
第一行创建一个 sed 脚本 (/tmp/script.sed),第二行实现它。假设您的状态列表保存在 /tmp/states.csv 中,您的 svg 文件保存在 /tmp/source.svg 中。
答案4
tr \[:upper:] \[:lower:] <csv.file | sort -bt, -uk1,1 |
sed -e'\|^ *\([[:alpha:]]\{2\}\) *, *\([[:alpha:]]\{1,\}\) *$|!d' \
-e's||s/\\(<g id="\1"\\)>/\\1 style="fill:\2;">/;t|' |
sed -f- svg.file