查找并替换双括号值

查找并替换双括号值

我需要将[[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 来完成其工作:

  1. mapfile读取输入文件(进入默认数组 MAPFILE),修剪尾随换行符 ( -t)

  2. 内置条件表达式[[,其唯一目的是从翻译文件中查找看起来像键=值对的行。正则表达式希望至少看到一个键的字符和一个值的字符。

  3. 然后它构建一个变量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"

相关内容