labunix's blog

labunixのラボUnix

Cisco CLIのsection風lsecの別バージョンを書いてみた。

■Cisco CLIのsection風lsecの別バージョンを書いてみた。
 セクションの中の検索でもちゃんと出力出来るようにしたので、より元のコマンドの出力に近づいた。

 Cisco CLIで使うsectionコマンドっぽいのをbash+awkで書いてみた。
 http://labunix.hateblo.jp/entry/20180909/1536501383

■前回は段落にスペースがあることにフォーカスしていたけど、
 今回は行頭が文字であることにフォーカスする。

$ cat myscripts/lsec 
#!/bin/bash
# Script Name	: The origin of the name of $0 is [L]inux [Sec]tion
# Last Update	: 2018/10/07
# Author	: labunix
# Description	: Like the Cisco CLI section command.
# 

if [ $# -ne 1 ];then
  echo "Usege: cat [text-file] | $0 [keyword|\"key word\"]"
  exit 1
fi

# 2018/09/10
#awk -v key="$1" 'BEGIN{f=0} \
#                  {if($0 ~ key) \
#                    {f=1;print $0} \
#                    else{if(f==1 && $0 ~ /^ /) \
#                      {print $0} \
#                    else{f=0} \
#                    } \
#                  }'

awk -v key="$1" 'BEGIN{f=0} \
  {if($0 ~ /^[A-z0-9]/){f++;a[f]=$0}else{a[f]=a[f]"___"$0}}\
  END{for(n in a){if(a[n] ~ key){gsub("___","\n",a[n]);print a[n]}}}'

■行内には「___」が無いことが前提。
 最初はf=0なので、次の行頭に文字が来るまではa[0]の連想配列に代入される。
 行頭の「!」は記号なので、そのままa[0]の配列に入る。

 awkで記号をエスケープしたいときに使う、文字と8進数の一覧
 http://labunix.hateblo.jp/entry/20180801/1533056689

$ echo "`seq 32 126`" | awk '{printf "%c,\\%03o\n",$1,$1}' | grep '!'
!,\041

$ find GNS3/ -type f -name "*.cfg" | tail -1 | xargs cat | lsec Last


!
! Last configuration change at 23:34:48 JST Sun Aug 12 2018
!

■ip addressが設定されているセクションとホスト名を出力する。

$ find GNS3/ -type f -name "*.cfg" | tail -1 | xargs cat | lsec ip.address.[0-9]\|hostname
hostname HTTP-R
!
interface Loopback0
 ip address 1.1.1.1 255.255.255.255
!
interface Ethernet0/1
 ip address 192.168.0.61 255.255.255.0
!
interface Ethernet1/3
 ip address 10.1.102.1 255.255.255.0
 no cdp enable
!
interface Serial2/0
 ip address 10.1.100.2 255.255.255.0
 serial restart-delay 0
 no cdp enable
!

■SHELL(bash)に解釈されないように「"」でエスケープすれば、よりそれっぽく書ける。
$ find GNS3/ -type f -name "*.cfg" | tail -1 | xargs cat | lsec "ip address 192.168.|hostname"
hostname HTTP-R
!
interface Ethernet0/1
 ip address 192.168.0.61 255.255.255.0
!

$ find GNS3/ -type f -name "*.cfg" | tail -1 | xargs cat | lsec "192.168.|hostname"
hostname HTTP-R
!
interface Ethernet0/1
 ip address 192.168.0.61 255.255.255.0
!

■パスワードが定義されているセクションとホスト名を検索する。

$ find GNS3/ -type f -name "*.cfg" | tail -1 | xargs cat | lsec "password|hostname"
no service password-encryption
!
hostname HTTP-R
!
enable password cisco
!
router bgp 100
 bgp log-neighbor-changes
 network 1.1.1.1 mask 255.255.255.255
 network 2.2.2.2 mask 255.255.255.255
 network 3.3.3.3 mask 255.255.255.255
 network 10.1.102.0 mask 255.255.255.0
 network 172.16.17.0 mask 255.255.255.0
 network 172.16.18.0 mask 255.255.255.0
 neighbor 10.1.100.1 remote-as 200
 neighbor 10.1.100.1 password cisco
 neighbor 10.1.100.1 update-source Serial2/0
 neighbor 10.1.102.2 remote-as 100
 neighbor 10.1.102.2 password cisco
 neighbor 10.1.102.2 update-source Ethernet1/3
!
line vty 0 4
 password cisco
 login
 transport input telnet
!
!

■「10.1.」のIPアドレスでセクションを検索すると、
 bgpルーティングの設定も出力される。

$ find GNS3/ -type f -name "*.cfg" | tail -1 | xargs cat | lsec "10.1.|hostname"
hostname HTTP-R
!
interface Ethernet1/3
 ip address 10.1.102.1 255.255.255.0
 no cdp enable
!
interface Serial2/0
 ip address 10.1.100.2 255.255.255.0
 serial restart-delay 0
 no cdp enable
!
router bgp 100
 bgp log-neighbor-changes
 network 1.1.1.1 mask 255.255.255.255
 network 2.2.2.2 mask 255.255.255.255
 network 3.3.3.3 mask 255.255.255.255
 network 10.1.102.0 mask 255.255.255.0
 network 172.16.17.0 mask 255.255.255.0
 network 172.16.18.0 mask 255.255.255.0
 neighbor 10.1.100.1 remote-as 200
 neighbor 10.1.100.1 password cisco
 neighbor 10.1.100.1 update-source Serial2/0
 neighbor 10.1.102.2 remote-as 100
 neighbor 10.1.102.2 password cisco
 neighbor 10.1.102.2 update-source Ethernet1/3
!