template_engine.sh bashテンプレートエンジン coneta #5
template_engine.sh
bashで使うテンプレートエンジン1です。
機能
- 「テンプテートファイル」の「被置換文字列」を「置換文字列」で置換後、「出力方法」に従って、結果を出力します。
- 「テンプテートファイル」、「被置換文字列」、「置換文字列」、「出力方法」は「データファイル」で定義します。
- 「データファイル」に任意のbashコマンドを記述(※)することにより、テンプレートエンジンの振る舞いを変更することがでます。
※ 1行で記述する必要がある。複数のコマンドを記述する場合は;
を使用します。
コマンドはbash
のeval
で評価されます。
- 「データファイル」の読み込み、「テンプレートファイル」の読み込み、「出力」はデフォルトで
cat
コマンドを使用していますが、環境変数にコマンドを設定することにより、別のコマンドに変更することができます。
※ この機能はextcatを使うことを想定して実装しましたが、他のコマンドを使うことも可能です。extcatは本スクリプトに組み込んであります。
※ 1行で記述する必要がある。複数のコマンドを記述する場合は
;
を使用します。コマンドは
bash
のeval
で評価されます。cat
コマンドを使用していますが、環境変数にコマンドを設定することにより、別のコマンドに変更することができます。※ この機能はextcatを使うことを想定して実装しましたが、他のコマンドを使うことも可能です。extcatは本スクリプトに組み込んであります。
No. | 環境変数 | 対象となる機能 |
---|---|---|
1 | CAT_DATA | データファイルの読み込み |
2 | CAT_TEMPLATE | テンプレートファイルの読み込み |
3 | CAT_OUTPUT | 出力 |
使用方法
【実行方法】
【データファイルを引数で指定する】
template_engine.sh [file [file]...]
【データファイルを標準入力に流し込む】
cat file | template_engine.sh
【データファイルの書式】
データファイル
CMD bashコマンド
DEF テンプレートファイル 被置換文字列1△被置換文字列2△被置換文字列n
DAT 出力方法 置換文字列1△置換文字列2△置換文字列n
【データファイルを引数で指定する】
template_engine.sh [file [file]...]
【データファイルを標準入力に流し込む】
cat file | template_engine.sh
CMD bashコマンド
DEF テンプレートファイル 被置換文字列1△被置換文字列2△被置換文字列n
DAT 出力方法 置換文字列1△置換文字列2△置換文字列n
CMD行:任意、複数行可。
DEF行:必須、以降のDAT行の被置換文字列、複数行可。
DAT行:必須、直前のDEF行の置換文字列、複数行可。
出力方法:
> ファイル #ファイルに上書き
>> ファイル #ファイルに追加
△:デフォルトはタブコード(0x09)です。環境変数に設定することにより、別の文字に変更することができます。
No. | 環境変数 | 対象となる機能 |
---|---|---|
1 | DAT_IFS | DAT行の読み込み |
2 | DEF_IFS | DEF行の読み込み |
被置換文字列:sedコマンドの正規表現
置換文字列:シングルクォート(0x27)とタブコード(0x09)以外の文字はそのまま記述します。
シングルクォート(0x27)は以下を記述します。
'\\\\\\\\''
タブコード(0x09)はCMD行で環境変数にタブコードを設定し、DAT行でその環境変数を参照します。
export XTAB='△'
△はタブコード、環境変数XTAB
は任意です、他の名前でも可。
'\\\\\\\"${XTAB}"'
【関連図】
※図中のsedのsコマンドは区切り文字に/
を使用していますが、実際は0x04を使用しています。
関連図のdotソース
digraph xxx{
node[shape=record fontname="MS Gothic"]
TEMPLATE_ENGINE[label="template_engine.sh データファイル"]
DATA_FILE
[label="{ データファイル|{CMD| bashコマンド }|{DEF| テンプレートファイル| 被置換文字列(複数可) }|{DAT| 出力方法\l >出力ファイル \l>>出力ファイル \l| 置換文字列(複数可) }}"];
TEMPLATE_FILE[label=" テンプレートファイル"]
OUTPUT[label=" 出力ファイル"]
edge [arrowhead=open style=dotted]
DATA_FILE:f1->TEMPLATE_FILE
DATA_FILE:f2->OUTPUT
TEMPLATE_ENGINE->DATA_FILE
edge [arrowhead=normal style=solid]
TEMPLATE_FILE->OUTPUT[ fontname="MS Gothic" label="sed s/被置換文字列/置換文字列/g" color="green"]
}
実行例
【テンプレートファイル】
template_file.txt
########################################
# @1@ @2@
# @2@ @1@
【データファイル】
data.txt
CMD rm result.txt 2> /dev/null
DEF template_file.txt "@1@" "@2@"
DAT >>result.txt "DATA 11 DATA21
DAT >>result.txt "DATA 12 ${HOME}DATA22
DAT >>result.txt "DATA 13'\\\\\\\\'' DATA23
CMD export XTAB=' '
DAT >>result.txt "DATA 14'\\\\\\\"${XTAB}"' DATA24
DAT >>result.txt DATA 15!"#$%&()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~@@@ DATA25
【実行】
template_engine.sh data.txt
【結果】
result.txt
########################################
# "DATA 11 DATA21
# DATA21 "DATA 11
########################################
# "DATA 12 ${HOME}DATA22
# ${HOME}DATA22 "DATA 12
########################################
# "DATA 13' DATA23
# DATA23 "DATA 13'
########################################
# "DATA 14 DATA24
# DATA24 "DATA 14
########################################
# DATA 15!"#$%@1@()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~@@@ DATA25
# DATA25 DATA 15!"#$%@1@()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~@@@
実装
template_engine.sh
#!/bin/bash
extcat () { cat $@ | bash <<< "cat <<< "\""$(cat)"\""" ; };export -f extcat
export CAT_DATA=${CAT_DATA:-"cat"}
export CAT_TEMPLATE=${CAT_TEMPLATE:-"cat"}
export CAT_OUTPUT=${CAT_OUTPUT:-"cat"}
export DEF=()
export CMD
export DAT
export TEMPLATE_FILE
export OUTPUT
export TAB_CODE=$(printf "\t")
main_proc(){
local line kind rest
${CAT_DATA} $@ | sed '/^#/d' | while read line
do
read kind rest <<< "${line}"
case "${kind}" in
DEF) func_DEF "${rest}";;
DAT) func_DAT "${rest}";;
CMD) func_CMD "${rest}";;
*)
esac
done
}
func_DEF(){
local line old_ifs rest i d
line=$1
old_ifs=${IFS}
IFS=${DEF_IFS:-${TAB_CODE}}
read TEMPLATE_FILE rest <<< "${line}"
i=0
unset DEF[@]
for d in ${rest}
do
eval DEF[i]="${d}"
((i+=1))
done
IFS=${old_ifs}
}
func_DAT(){
local line old_ifs rest i d
local sed_s_command_delimiter=$(echo -n -e '\x04')
line=$1
old_ifs=${IFS}
IFS=${DAT_IFS:-${TAB_CODE}}
read OUTPUT rest <<< "${line}"
i=0
{
printf "${CAT_TEMPLATE} ${TEMPLATE_FILE} | sed '\n"
for d in ${rest}
do
printf 's'${sed_s_command_delimiter}'%s'${sed_s_command_delimiter}'%s'${sed_s_command_delimiter}'g\n' "${DEF[i]}" "${d}"
((i+=1))
done
printf "' | ${CAT_OUTPUT} ${OUTPUT}\n"
} | bash
IFS=${old_ifs}
}
func_CMD(){
eval "$1"
}
main_proc $@
環境
########################################
# @1@ @2@
# @2@ @1@
CMD rm result.txt 2> /dev/null
DEF template_file.txt "@1@" "@2@"
DAT >>result.txt "DATA 11 DATA21
DAT >>result.txt "DATA 12 ${HOME}DATA22
DAT >>result.txt "DATA 13'\\\\\\\\'' DATA23
CMD export XTAB=' '
DAT >>result.txt "DATA 14'\\\\\\\"${XTAB}"' DATA24
DAT >>result.txt DATA 15!"#$%&()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~@@@ DATA25
template_engine.sh data.txt
########################################
# "DATA 11 DATA21
# DATA21 "DATA 11
########################################
# "DATA 12 ${HOME}DATA22
# ${HOME}DATA22 "DATA 12
########################################
# "DATA 13' DATA23
# DATA23 "DATA 13'
########################################
# "DATA 14 DATA24
# DATA24 "DATA 14
########################################
# DATA 15!"#$%@1@()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~@@@ DATA25
# DATA25 DATA 15!"#$%@1@()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~@@@
#!/bin/bash
extcat () { cat $@ | bash <<< "cat <<< "\""$(cat)"\""" ; };export -f extcat
export CAT_DATA=${CAT_DATA:-"cat"}
export CAT_TEMPLATE=${CAT_TEMPLATE:-"cat"}
export CAT_OUTPUT=${CAT_OUTPUT:-"cat"}
export DEF=()
export CMD
export DAT
export TEMPLATE_FILE
export OUTPUT
export TAB_CODE=$(printf "\t")
main_proc(){
local line kind rest
${CAT_DATA} $@ | sed '/^#/d' | while read line
do
read kind rest <<< "${line}"
case "${kind}" in
DEF) func_DEF "${rest}";;
DAT) func_DAT "${rest}";;
CMD) func_CMD "${rest}";;
*)
esac
done
}
func_DEF(){
local line old_ifs rest i d
line=$1
old_ifs=${IFS}
IFS=${DEF_IFS:-${TAB_CODE}}
read TEMPLATE_FILE rest <<< "${line}"
i=0
unset DEF[@]
for d in ${rest}
do
eval DEF[i]="${d}"
((i+=1))
done
IFS=${old_ifs}
}
func_DAT(){
local line old_ifs rest i d
local sed_s_command_delimiter=$(echo -n -e '\x04')
line=$1
old_ifs=${IFS}
IFS=${DAT_IFS:-${TAB_CODE}}
read OUTPUT rest <<< "${line}"
i=0
{
printf "${CAT_TEMPLATE} ${TEMPLATE_FILE} | sed '\n"
for d in ${rest}
do
printf 's'${sed_s_command_delimiter}'%s'${sed_s_command_delimiter}'%s'${sed_s_command_delimiter}'g\n' "${DEF[i]}" "${d}"
((i+=1))
done
printf "' | ${CAT_OUTPUT} ${OUTPUT}\n"
} | bash
IFS=${old_ifs}
}
func_CMD(){
eval "$1"
}
main_proc $@
環境
ホスト Windows10 COREi7
VM VirtualBox バージョン 5.2.8 r121009 (Qt5.6.2)
CentOS Linux release 7.4.1708 (Core)
3.10.0-693.21.1.el7.x86_64 #1 SMP Wed Mar 7 19:03:37 UTC 2018
GNU bash, バージョン 4.2.46(2)-release (x86_64-redhat-linux-gnu)
Author And Source
この問題について(template_engine.sh bashテンプレートエンジン coneta #5), 我々は、より多くの情報をここで見つけました https://qiita.com/EjiriAkira/items/218cb17a060ce3d5aedd著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .