我需要将[[KEY]]
其中一个 html 文件中的双括号替换为VALUE
.键值在不同的文件中可用。替换后,我需要将输出放在单独的文件中。
因此,我们有两个输入文件和一个输出文件作为参数。
html 文件:foo.html
<html>
<head>
<title>[[title]]</tittle>
</head>
<body>[[body]]</body>
</html>
属性文件:foo.properties
title=foo title
body= foo body
输出文件
<html>
<head>
<title>foo title</tittle>
</head>
<body>foo body</body>
</html>
如何通过在参数中传递所有文件名来创建 bash 脚本?
答案1
和sed
:
sed -f <(sed 's/\(.*\)=\(.*\)/s\/\\[\\[\1\\]\\]\/\2\//' foo.properties) foo.html
内部调用构建搜索和替换对,然后由外部 sed 通过(脚本文件)sed
读取。-f
它sed
从文件创建命令foo.properties
如下:
s/\[\[name\]\]/replace string/
这些是针对第二个文件读取和执行的foo.html
。
答案2
Eric Renouf 是对的,bash 可能不是最好的工具;但这并没有阻止我尝试!
以下脚本使用一堆 bash-ism 来完成其工作:
mapfile
读取输入文件(进入默认数组 MAPFILE),修剪尾随换行符 (-t
)内置条件表达式
[[
,其唯一目的是从翻译文件中查找看起来像键=值对的行。正则表达式希望至少看到一个键的字符和一个值的字符。然后它构建一个变量
expr
用作 sed 表达式。
bash 脚本:
#!/usr/bin/env bash
# Usage: $0 [input file] [translation file] [output file]
mapfile -t < "$2"
expr=""
for keyvalue in "${MAPFILE[@]}"
do
if [[ $keyvalue =~ (.+)=(.+) ]]
then
k="${BASH_REMATCH[1]}"
v="${BASH_REMATCH[2]}"
expr="$expr s/\[\[$k\]\]/$v/g;"
fi
done
sed "$expr" "$1" > "$3"
如果我专注的话,我会在输入文件上再次使用 mapfile,循环遍历 MAPFILE 转换数组并${parameter/pattern/string}
在每个输入行上使用扩展以写入新的输出文件。也许以后吧!
用法:scriptname foo.html foo.properties outputfoo.html
当在 OP 的示例输入文件上运行时,outputfoo.html 包含:
<html>
<head>
<title>foo title</tittle>
</head>
<body> foo body</body>
</html>
...包括“foo body”的前导空间!
后来发生了
我很好奇,并想出了上述内容的更 bash 版本。它不使用 sed,而是在循环输入文件时在每次替换时使用 bash 的参数扩展。
#!/usr/bin/env bash
# Usage: $0 [input file] [translation file] [output file]
mapfile -t < "$2"
declare -A replacements
for keyvalue in "${MAPFILE[@]}"
do
if [[ $keyvalue =~ (.+)=(.+) ]]
then
k="${BASH_REMATCH[1]}"
v="${BASH_REMATCH[2]}"
replacements[$k]="$v"
fi
done
mapfile -t < "$1"
for line in "${MAPFILE[@]}"
do
for pattern in "${!replacements[@]}"
do
line="${line//\[\[$pattern\]\]/${replacements[$pattern]}}"
done
printf "%s\n" "$line"
done > "$3"