Tera Termマクロで複数行から任意の文字列を抽出【recvln】【strdim】
目次
この記事の目的
・Tera Termマクロの基本的な操作は一通り利用可能。
・showコマンド等、複数行のレスポンスから必要な文字列だけを抜き出し、別の処理に利用したい。
このような方向けに、Tera Termマクロの「recvln」と「strdim」コマンドを利用して実現する方法をまとめています。
「recvln」とは
recvlnは「recieve line」を意図したコマンドと推察されます。
Tera Termマクロのコマンドリファレンス(recvln)によると、文字通り「一行分の文字を受信する。」コマンドです。
recvln1回につき、受診した文字列一行分がシステム変数 「inputstr 」に格納されます。
以下にrecvlnの処理の図解を示します。
ここでポイントとなるのは、recvlnで受信するのはあくまでも「一行分」の文字列であること。
例えばルーターでshowコマンドを打鍵した際には、基本的に数行から数十行に渡ってレスポンスが表示されます。
そこで普通にrecvlnを使おうとしても、recvln一行の記述につきレスポンス一行分しかinputstrとして取得できません。
これではrecvlnを数十行に渡ってrecvlnをマクロに羅列することになり、処理全般が煩雑で不便なものとなります。
そこで、次に紹介する「strdim」を組み合わせることで、より合理的で簡潔な記述が可能となります。
「strdim」とは
strdimは「strings dim」を意図したコマンドと推察されます。
stringsは文字列の意味です。
dimはプログラミング全般で配列や変数を宣言する際に使われます。元々は「dimension」を略したものです。
Tera Termマクロのコマンドリファレンス(strdim)によると、「指定した数の要素を持つ、文字列配列型の変数を宣言する。」コマンドです。
注:上記コマンドリファレンスの解説には「整数配列型」とありますが、これは誤植であると想定し、同ページの冒頭に記載の通り「文字列配列型」が正だとみなします。
strdim [array] [size]
・array:配列の名前を宣言
・size:配列の要素の個数を宣言(※配列の添字は0から起算)
前項で言及しましたが、recvlnを使っても複数行のレスポンスから一行分しか受信できないことがネックでした。
このstrdimを利用し、showコマンドのレスポンス全行分を1行ずつ配列に格納することで、当初の目的を実現します。
以下にstrdimの処理の図解を示します。
ここではshow ip routeのレスポンス3行分を格納するための配列として、「SIR[0]~SIR[2]」を作成しています。
任意の文字列を要素として収納可能な、空き箱を3箱用意するようなものとイメージしてください。
for文で全行分を配列に格納
次に、for文のループ処理を利用し、showコマンドのレスポンス全行分をstrdimで宣言した配列SIRに格納します。
以下の図解では、「for i 0 2」~「next」の4行で処理するマクロを示しています。
ここではshow ip routeのレスポンスが3行だけなので、配列SIRの添え字はSIR[2]最大2です。
そのため、for文のカウンタ変数iの上限も2となります。
この変数iの上限はケースバイケース。もしレスポンスが10行であれば9となり、50行であれば49となります。
即ち前者は「for i 0 9」で後者は「for i 0 49」となり、変更箇所は最小限に留まります。
これはつまり、たとえレスポンスが何行であろうと臨機応変に対応できるということです。
次に、1ループ目の処理を以下に図示します。
1ループ目では、for文で「i=0」のケースが処理されます。
recvlnで1行目のレスポンスを受信すると、暫定的にinputstrに格納されます。
その後、「SIR[0] = inputstr」とすることで、配列SIR[0]に恒久的に格納されます。
以下の図解は、1ループ目が完了した時点です。
配列SIR[0]の中に、レスポンス1行目「C 192.168.1.0/24 is directly connected, Vlan10」が格納されました。
次に、2ループ目の処理を以下に図示します。
1ループ目と同様に、for文で「i=1」のケースが処理されます。
recvlnで2行目のレスポンスが配列SIR[1]に格納されます。
以下の図解は、2ループ目が完了した時点です。
配列SIR[1]の中に、レスポンス2行目「C 192.168.2.0/24 is directly connected, Vlan20」が格納されました。
ここまでの流れで既にご想像頂けたかと思われますが、念のため3ループ目の処理も以下に図示します。
3ループ目では、for文のカウンタ上限である「i=2」のケースが処理され、for文の処理は完了します。
recvlnで3行目のレスポンスが配列SIR[2]に格納されます。
最後に、3ループ目の完了時点を以下に図示します。
配列SIR[2]の中に、レスポンス1行目「S 192.168.3.0/24 [1/0] via 192.168.1.2」が格納されました。
これで全行分のレスポンスが配列SIRに格納された状態です。
配列に格納された要素の抽出
格納された要素からどれか一つを抽出するには、SIR[0]やSIR[1]などと配列の添え字で指定します。
一例として、SIR[3]の要素を「dispstr」コマンドでコンソールに表示するマクロを以下に図示します。
ここまでの一連の処理の後に「dispstr SIR[2]」をマクロ上で実行すると、SIR[2]に格納されている要素である、レスポンスの3行目がコンソールに表示されます。
配列SIRは文字列型変数なので、様々な形での処理が可能です。
例えば、以下の様な処理が想定されます。
- 格納されたレスポンス行に対して、strmatchコマンドで正規表現によるパターンマッチングを行い、IPアドレスを抽出する。
- 抽出したIPアドレスをstrconcatコマンドで任意の文字列と結合し、pingやルーティング設定を行う。
実際に必要となる処理に応じて、柔軟にご対応下さい。
本記事に関するご質問やご意見等は、下記のコメント欄かTwitterのDMをご利用ください。