• 土. 11月 23rd, 2024

~下町物語~

入り組んだ現代社会に鋭いメスを入れ、おもしろおかしく書く綴るブログである。

正規表現チェッカー?を作ってみた。

この記事を読む およそ時間 4

○シェル概要
正規表現が苦手ということで、sedを使ったちょっとした
正規表現チェッカーを作成する事にした。

sedは色々できるのだが、多くはファイル内の文字列置換に使われたり
シェルの中でシェルに渡される文字列を置換したりする
その時、正規表現を使い処理する目的に使われる。

よって、sedに正規表現をぶつけることで、
正規表現が正しい物かをチェックできることから作成を行った。

○前提
シェルの置き場所    :/script/com/配下
置換する元テストファイル:/script/com/testpattern/配下
練習問題用ファイル   :/script/com/testpattern/zzz.txt  (問題質問)
練習問題用ファイル   :/script/com/testpattern/zzz-a.txt (問題回答)
書出されるディレクトリ :/script/com/testpattern/配下
き出されるファイル名  :sed-yyyy-mm-dd-**_**_**.output.txt

リストには、output/zzzがつく文字列のファイルはリストアップしない仕組みとした。

シェルは、今後練習問題を拡張することもあると思うので
function形式で作成した。

○改修ポイント
今シェルの置き場所等、あえて変数化していないが
どこかで固定でおくなら変数化するのが好ましい。

また、使い方として今はあえてメニュー形式にしたが
$1 $2の引数形式で入力も良いと思うが、
そうなってくるとsedコマンドを叩いた方が速い為
このシェルの意味が薄れていく可能性が高い。
あえて学習するということを前提に作ったシェルである。

○問題練習を増やす方法は以下の通り

部品1(以下の部分を3.問題練習1とする・4.終了を5に変更)
echo “################### Menu ##################”
echo “”
echo ” 1.正規表現チェック”
echo “”
echo ” 2.使い方表示”
echo “”
echo ” 3.練習問題”
echo “”
echo ” 4.終了”
echo””
echo “###########################################”

部品2(同様に FUNC_mondai2を作成し4)→5)に変更)
3)
FUNC_mondai1
;;
4)
echo “正規表現チェッカーを終了します”
exit 0
;;

部品3(FUNC_mondai1→FUNC_mondai2に変更して問題を書き換える)
/script/com/testpattern配下に元ファイルを作成して
正規表現で期待値になるファイルを作成しシェル内部に記載する。
diff でリターン値が0が帰ってくる仕様で正解か不正解を判定しています。

function FUNC_mondai1
{
echo “AAA BBB CCC DDD BBB という文字列がある”
echo “上記文字列をAAA ZZZ CCC DDD ZZZ に変更したい場合の正規表現を考えて入力してください。”
echo “”
echo “AAA BBB CCC DDD BBB”
echo “↓↓↓↓↓↓↓↓↓↓”
echo “AAA ZZZ CCC DDD ZZZ”
echo “”

read TINPUT
cat /script/com/check.txt | /bin/sed -e “s${TINPUT}/g” > /dev/null 2>&1
if [ $? = 1 ]
then
echo “入力した正規表現【$SEDINPUT】が間違っています”
echo “もう一度入力してください。”
sleep 5
FUNC_mondai1
else
cat /script/com/testpattern/zzz.txt | /bin/sed -e “s${TINPUT}/g” > /tmp/a.txt
diff /tmp/a.txt /script/com/testpattern/zzz-a.txt > /dev/null 2>&1
if [ $? = 1 ];
then
echo “不正解です。http://hydrocul.github.io/wiki/commands/sed.html で確認して再度入力してくださ
い。”
sleep 10
rm -rf /tmp/a.txt
clear
FUNC_mondai1
else
echo “正解です。”
rm -rf /tmp/a.txt
sleep 10
FUNC_menu
fi
fi
}

○処理結果(正常パターン)エビデンス

1.チェッカ
################### Menu ##################

1.正規表現チェック

2.使い方表示

3.練習問題

4.終了

###########################################
1
置換対象ファイルを入力してください
###### List ########
aaa.txt
####################
aaa.txt
対象ファイルは aaa.txtですね
良ければ(y/n)
y
テストしたい正規表現を入れてください
/abc/aBC
入力した正規表現で処理した結果を表示します。
###################################################
変更された部分を表示します。
1c1
< abc Abc aBc abC AbC AAA abe kkk bbb eee ccc

> aBC Abc aBc abC AbC AAA abe kkk bbb eee ccc
###################################################
結果をアウトプットしますか?
y
アウトプットファイルは【/script/com/testpattern/sed-2014-12-15-13_07_39.output.txt】です。

●ファイル指定が間違っている場合
################### Menu ##################

1.正規表現チェック

2.使い方表示

3.練習問題

4.終了

###########################################
1
置換対象ファイルを入力してください
###### List ########
aaa.txt
####################
bbbbb.txt
対象ファイルがありません

●テストパターン正規表現が間違っている場合
################### Menu ##################

1.正規表現チェック

2.使い方表示

3.練習問題

4.終了

###########################################
1
置換対象ファイルを入力してください
###### List ########
aaa.txt
####################
aaa.txt
対象ファイルは aaa.txtですね
良ければ(y/n)
y
テストしたい正規表現を入れてください
/aaabbb
入力した正規表現【/aaabbb】が間違っています

正規表現チェッカの使い方

例>対象ファイルからabcという文字列をABCに変換した場合 -> 【/abc/ABC】と入力する

その他詳細なオプションを組み込むことが可能
———————————————————————-
|メタ文字|意味 |
———————————————————————-
|^ |先頭 |
———————————————————————-
|$ |後尾 |
———————————————————————-
|. |任意の 1 文字 |
———————————————————————-
|* |直前の文字の 0 回以上の繰り返し |
———————————————————————-
|\+ |直前の文字の 1 回以上の繰り返し |
———————————————————————-
|\? |直前の文字が 0 回または 1 回のみ出現 |
———————————————————————-
|[] |文字クラス、[abc0-9] ならば数字と a, b, c のどれか 1 文字 |
———————————————————————-
|\| |OR、[ab|ap] ならば ab または ap |
———————————————————————-
|\{3\} |直前の文字が 3 回だけ出現 |
———————————————————————-
|\{3,5\} |直前の文字が 3?5 回出現 |
———————————————————————-
|\b |単語区切り |
———————————————————————-

参考サイト http://hydrocul.github.io/wiki/commands/sed.html
メニューに戻る(y/n)

2.使い方表示(正常パターン)
################### Menu ##################

1.正規表現チェック

2.使い方表示

3.練習問題

4.終了

###########################################
2
正規表現チェッカの使い方

例>対象ファイルからabcという文字列をABCに変換した場合 -> 【/abc/ABC】と入力する

その他詳細なオプションを組み込むことが可能
———————————————————————-
|メタ文字|意味 |
———————————————————————-
|^ |先頭 |
———————————————————————-
|$ |後尾 |
———————————————————————-
|. |任意の 1 文字 |
———————————————————————-
|* |直前の文字の 0 回以上の繰り返し |
———————————————————————-
|\+ |直前の文字の 1 回以上の繰り返し |
———————————————————————-
|\? |直前の文字が 0 回または 1 回のみ出現 |
———————————————————————-
|[] |文字クラス、[abc0-9] ならば数字と a, b, c のどれか 1 文字 |
———————————————————————-
|\| |OR、[ab|ap] ならば ab または ap |
———————————————————————-
|\{3\} |直前の文字が 3 回だけ出現 |
———————————————————————-
|\{3,5\} |直前の文字が 3?5 回出現 |
———————————————————————-
|\b |単語区切り |
———————————————————————-

参考サイト http://hydrocul.github.io/wiki/commands/sed.html
メニューに戻る(y/n)
y

○使い方表示でメニューに戻らないを選択した場合
################### Menu ##################

1.正規表現チェック

2.使い方表示

3.練習問題

4.終了

###########################################
2
正規表現チェッカの使い方

例>対象ファイルからabcという文字列をABCに変換した場合 -> 【/abc/ABC】と入力する

その他詳細なオプションを組み込むことが可能
———————————————————————-
|メタ文字|意味 |
———————————————————————-
|^ |先頭 |
———————————————————————-
|$ |後尾 |
———————————————————————-
|. |任意の 1 文字 |
———————————————————————-
|* |直前の文字の 0 回以上の繰り返し |
———————————————————————-
|\+ |直前の文字の 1 回以上の繰り返し |
———————————————————————-
|\? |直前の文字が 0 回または 1 回のみ出現 |
———————————————————————-
|[] |文字クラス、[abc0-9] ならば数字と a, b, c のどれか 1 文字 |
———————————————————————-
|\| |OR、[ab|ap] ならば ab または ap |
———————————————————————-
|\{3\} |直前の文字が 3 回だけ出現 |
———————————————————————-
|\{3,5\} |直前の文字が 3?5 回出現 |
———————————————————————-
|\b |単語区切り |
———————————————————————-

参考サイト http://hydrocul.github.io/wiki/commands/sed.html
メニューに戻る(y/n)
n
[root@aaa com]#

●使い方表示でy/n以外を押した場合
################### Menu ##################

1.正規表現チェック

2.使い方表示

3.練習問題

4.終了

###########################################
2
正規表現チェッカの使い方

例>対象ファイルからabcという文字列をABCに変換した場合 -> 【/abc/ABC】と入力する

その他詳細なオプションを組み込むことが可能
———————————————————————-
|メタ文字|意味 |
———————————————————————-
|^ |先頭 |
———————————————————————-
|$ |後尾 |
———————————————————————-
|. |任意の 1 文字 |
———————————————————————-
|* |直前の文字の 0 回以上の繰り返し |
———————————————————————-
|\+ |直前の文字の 1 回以上の繰り返し |
———————————————————————-
|\? |直前の文字が 0 回または 1 回のみ出現 |
———————————————————————-
|[] |文字クラス、[abc0-9] ならば数字と a, b, c のどれか 1 文字 |
———————————————————————-
|\| |OR、[ab|ap] ならば ab または ap |
———————————————————————-
|\{3\} |直前の文字が 3 回だけ出現 |
———————————————————————-
|\{3,5\} |直前の文字が 3?5 回出現 |
———————————————————————-
|\b |単語区切り |
———————————————————————-

参考サイト http://hydrocul.github.io/wiki/commands/sed.html
メニューに戻る(y/n)

n以外を入れるとメニューに戻る仕様

3.練習問題
################### Menu ##################

1.正規表現チェック

2.使い方表示

3.練習問題

4.終了

###########################################
3
AAA BBB CCC DDD BBB という文字列がある
上記文字列をAAA ZZZ CCC DDD ZZZ に変更したい場合の正規表現を考えて入力してください。

AAA BBB CCC DDD BBB
↓↓↓↓↓↓↓↓↓↓
AAA ZZZ CCC DDD ZZZ

/BBB/ZZZ
正解です。

################### Menu ##################

1.正規表現チェック

2.使い方表示

3.練習問題

4.終了

###########################################
3
AAA BBB CCC DDD BBB という文字列がある
上記文字列をAAA ZZZ CCC DDD ZZZ に変更したい場合の正規表現を考えて入力してください。

AAA BBB CCC DDD BBB
↓↓↓↓↓↓↓↓↓↓
AAA ZZZ CCC DDD ZZZ

/BBB/aaa
不正解です。http://hydrocul.github.io/wiki/commands/sed.html で確認して再度入力してください。

○シェル本体

#!/bin/sh
##++ =======================================================================================
## System : 正規化表現チェッカー
## Emp-division :
## Transaction :
## Calling-sequence : sed-check.sh
## Option : null
## Parameters :
## Return : 0 正常終了
## : 1 異常終了
## Structure :
## Abstract :
## Modify : 2014/12/15 楠 新規作成
##– ======================================================================================
#set -x

#++ ++++++++++++++++++++++++++++++++++++++++++
# 環境変数
#– ——————————————
dtm=`date +%Y-%m-%d-%H_%M_%S`

#++ +++++++++++++++++++++++++++++++++++++++++++
# メニュー
#– ——————————————-
function FUNC_menu
{
clear

echo “################### Menu ##################”
echo “”
echo ” 1.正規表現チェック”
echo “”
echo ” 2.使い方表示”
echo “”
echo ” 3.練習問題”
echo “”
echo ” 4.終了”
echo””
echo “###########################################”
read comon1
case $comon1 in
1)
FUNC_checker
;;
2)
FUNC_help
;;
3)
FUNC_mondai1
;;
4)
echo “正規表現チェッカーを終了します”
exit 0
;;
*)
echo “-> オプションが不明です”
sleep 2
clear
FUNC_menu
esac
}

function FUNC_checker
{
echo “置換対象ファイルを入力してください”
echo “###### List ########”
ls /script/com/testpattern/ | grep -v output | grep -v zzz
echo “####################”
read TF

if [ ! -e “/script/com/testpattern/${TF}” ]
then
echo “対象ファイルがありません”
sleep 5
FUNC_menu
else
echo “対象ファイルは ${TF}ですね “
echo “良ければ(y/n)”
read CINPUT
if [ ${CINPUT} = “y” ]
then
echo “テストしたい正規表現を入れてください”
read SEDINPUT
cat /script/com/check.txt | /bin/sed -e “s${SEDINPUT}/g” > /dev/null 2>&1
if [ $? = 1 ]
then
echo “入力した正規表現【$SEDINPUT】が間違っています”
FUNC_help
else
echo “入力した正規表現で処理した結果を表示します。”
cat /script/com/testpattern/${TF} | /bin/sed -e “s${SEDINPUT}/g” > /script/com/testpattern/sed-${dtm}.txt
if [ $? = 1 ];then
echo “チェック処理が心配しました”
rm -rf /script/com/testpattern/sed-${dtm}.txt
sleep 5
FUNC_help
fi

echo “###################################################”
echo “変更された部分を表示します。”
diff /script/com/testpattern/${TF} /script/com/testpattern/sed-${dtm}.txt
echo “###################################################”
echo “結果をアウトプットしますか?”
read COUTPUT

if [ ${COUTPUT} = “y” ]
then
mv /script/com/testpattern/sed-${dtm}.txt /script/com/testpattern/sed-${dtm}.output.txt
echo “アウトプットファイルは【/script/com/testpattern/sed-${dtm}.output.txt】です。”
sleep 5
FUNC_menu
else
rm -rf /script/com/testpattern/sed-${dtm}.txt
FUNC_menu
fi
fi
fi
fi
}

function FUNC_mondai1
{
echo “AAA BBB CCC DDD BBB という文字列がある”
echo “上記文字列をAAA ZZZ CCC DDD ZZZ に変更したい場合の正規表現を考えて入力してください。”
echo “”
echo “AAA BBB CCC DDD BBB”
echo “↓↓↓↓↓↓↓↓↓↓”
echo “AAA ZZZ CCC DDD ZZZ”
echo “”

read TINPUT
cat /script/com/check.txt | /bin/sed -e “s${TINPUT}/g” > /dev/null 2>&1
if [ $? = 1 ]
then
echo “入力した正規表現【$SEDINPUT】が間違っています”
echo “もう一度入力してください。”
sleep 5
FUNC_mondai1
else
cat /script/com/testpattern/zzz.txt | /bin/sed -e “s${TINPUT}/g” > /tmp/a.txt
diff /tmp/a.txt /script/com/testpattern/zzz-a.txt > /dev/null 2>&1
if [ $? = 1 ];
then
echo “不正解です。http://hydrocul.github.io/wiki/commands/sed.html で確認して再度入力してください。”
sleep 10
rm -rf /tmp/a.txt
clear
FUNC_mondai1
else
echo “正解です。”
rm -rf /tmp/a.txt
sleep 10
FUNC_menu
fi
fi
}

function FUNC_help
{
echo “正規表現チェッカの使い方”
echo “”
echo “例>対象ファイルからabcという文字列をABCに変換した場合 -> 【/abc/ABC】と入力する”
echo “”
echo “その他詳細なオプションを組み込むことが可能”
echo “———————————————————————-“
echo “|メタ文字|意味 |”
echo “———————————————————————-“
echo “|^ |先頭 |”
echo “———————————————————————-“
echo “|$ |後尾 |”
echo “———————————————————————-“
echo “|. |任意の 1 文字 |”
echo “———————————————————————-“
echo “|* |直前の文字の 0 回以上の繰り返し |”
echo “———————————————————————-“
echo “|\+ |直前の文字の 1 回以上の繰り返し |”
echo “———————————————————————-“
echo “|\? |直前の文字が 0 回または 1 回のみ出現 |”
echo “———————————————————————-“
echo “|[] |文字クラス、[abc0-9] ならば数字と a, b, c のどれか 1 文字 |”
echo “———————————————————————-“
echo “|\| |OR、[ab|ap] ならば ab または ap |”
echo “———————————————————————-“
echo “|\{3\} |直前の文字が 3 回だけ出現 |”
echo “———————————————————————-“
echo “|\{3,5\} |直前の文字が 3?5 回出現 |”
echo “———————————————————————-“
echo “|\b |単語区切り |”
echo “———————————————————————-“
echo “”
echo “参考サイト http://hydrocul.github.io/wiki/commands/sed.html “

echo “メニューに戻る(y/n)”
read CMENU
if [ -n “$CMENU” ]
then
if [ ${CMENU} = “y” ]
then
FUNC_menu
else
exit 0
fi
else
echo $CMENU
sleep 4
FUNC_menu
fi
}

#++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# メイン処理
#– ————————————————————
FUNC_menu

Translate »