二重括弧値の検索と置換

二重括弧値の検索と置換

[[KEY]]HTMLファイルの1つの二重括弧をVALUE別のファイルで使用できる.key値に置き換える必要があります。交換したら、出力を別のファイルに入れる必要があります。

したがって、パラメータには2つの入力ファイルと1つの出力ファイルがあります。

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/

これらは2番目のファイルに対して読み取られ実行されますfoo.html

答え2

Eric Renoufの言葉は正しいです。 bashは最高のツールではないかもしれませんが、それでも私が試してみるのを止めることはできませんでした!

次のスクリプトは、複数のbash-ismsを使用して操作を実行します。

  1. mapfile入力ファイルを読み込む(デフォルトの配列MAPFILEで)、末尾の改行文字を切り取る(-t

  2. [[キーと値のペアのように見える翻訳ファイルで行を見つけることが唯一の目的である組み込み条件式です。正規表現は、キーに対して少なくとも 1 つの文字と値に対して 1 つの文字を表示することを期待します。

  3. expr次に、sed式として使用する変数を作成します。

バッシュスクリプト:

#!/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"

関連情報