Cisco MDSのZone参照コマンド(Show Zone)を成形するスクリプトをChatGPTに作ってもらった

最近になってCisco MDSシリーズをちょこっとだけ触るようになったのですが、`show zone`などの結果と設計書との突合せがしんどいので、成形するスクリプトをChatGPTさんに作ってもらいました。
出力例も全部ChatGPTさんにもらったので、ChatGPTの使い方としてもよいのではないかと思います。
※出力例をクローズド環境から持ってこなくていい(機密情報とか考えなくていい)のが実は一番うれしいかも

英語のほうが精度が高い、と言われたので、最初はDeepLで英語翻訳してから質問を投げています。
が、途中から面倒になって日本語で投げてますｗ

# Show Zone

## 出力例を知りたい

### ChatGPTへの質問

Can you give me an example of running "show zone" in Cisco MDS?
`Cisco MDSで "show zone "を実行した場合の例を教えてください。`

### 回答

```
switch# show zone
zone name Zone1 vsan 100
  member pwwn 50:01:43:80:08:4c:4f:20
  member pwwn 50:01:43:80:08:4c:4f:21
  member pwwn 50:01:43:80:08:4c:4f:22
zone name Zone2 vsan 100
  member pwwn 50:01:43:80:08:4c:4f:23
  member pwwn 50:01:43:80:08:4c:4f:24
```
In this example, the "show zone" command displays information about the configured zones on a Cisco MDS switch. The output shows two zones named "Zone1" and "Zone2", both configured in VSAN 100. The members of each zone are listed, identified by their PWWN (Port World Wide Name) addresses.
`この例では、「show zone」コマンドは、Cisco MDSスイッチに設定されたゾーンに関する情報を表示します。出力には、「Zone1」と「Zone2」という名前の2つのゾーンが表示され、どちらもVSAN 100に構成されています。各ゾーンのメンバーは、PWWN（Port World Wide Name）アドレスで識別されてリストアップされます。`

## スクリプト生成(Shell & awk)

### 質問

Create a shell or awk script that creates a table of the following form based on this example
`以下のような形の表に成型するシェルまたはawkのスクリプトを教えて`

zone name vsan member pwwn member pwwn member pwwn 
Zone1 100 50:01:43:80:08:4c:4f:20 50:01:43:80:08:4c:4f:21 50:01:43:80:08:4c:4f:22
Zone2 100 50:01:43:80:08:4c:4f:23 50:01:43:80:08:4c:4f:24

### 回答


Here's an example shell script that uses awk to create a table in the format you requested based on the output of the "show zone" command:

bash
```shell
#!/bin/bash

show_zone_output=$(show zone)

echo "zone name vsan member pwwn member pwwn member pwwn"

echo "$show_zone_output" | awk '/^zone name/ {
    zone_name=$3
    vsan=$5
    printf "%-7s %-4s", zone_name, vsan
}
/member pwwn/ {
    printf " %s", $3
}
END {
    print ""
}'
```
This script first captures the output of the "show zone" command and then uses awk to parse the output and print it in the desired table format.

The awk script uses regular expressions to match the lines containing the zone name and the member PWWNs. For each line containing a zone name, it saves the zone name and VSAN values in variables. For each line containing a member PWWN, it appends the PWWN value to a string of PWWNs associated with that zone. When awk encounters a new zone name, it prints out the values for the previous zone and starts capturing PWWNs for the new zone. Finally, when awk reaches the end of the input, it prints out the values for the last zone.

Note that this script assumes that the output of the "show zone" command is saved in the variable show_zone_output. You may need to modify this script if you want to run the "show zone" command within the script or if the output of the command is saved in a file

このスクリプトは、まず「show zone」コマンドの出力をキャプチャし、次に awk を使って出力を解析し、希望の表形式で表示します。

awk スクリプトは正規表現を使用して、ゾーン名とメンバー PWWN を含む行をマッチさせます。ゾーン名を含む各行に対して、ゾーン名と VSAN 値を変数に保存します。メンバーPWWNを含む各行に対して、そのPWWN値をそのゾーンに関連するPWWNの文字列に追加します。awk は新しいゾーン名に出会うと、前のゾーンの値を出力し、新しいゾーンの PWWN のキャプチャを開始します。最後に、awk は入力の最後に到達すると、最後のゾーンの値を出力します。

このスクリプトは "show zone" コマンドの出力が変数 show_zone_output に保存されていると仮定していることに注意してください。スクリプト内で "show zone" コマンドを実行したい場合や、コマンドの出力がファイルに保存されている場合は、このスクリプトを修正する必要があるかもしれません。`

## (カンマにし忘れ)列の区切り文字をカンマにしたい

### 質問

列の区切り文字をカンマにしたい
※ここからめんどくさくなって日本語のまま質問投げちゃいました

### 回答

表の列をカンマで区切るように、awkスクリプトを変更することができます。以下に、変更したスクリプトを示します。
```
#!/bin/bash

show_zone_output=$(show zone)

echo "zone name,vsan,member pwwn,member pwwn,member pwwn"

echo "$show_zone_output" | awk '/^zone name/ {
    zone_name=$3
    vsan=$5
    printf "%s,%s", zone_name, vsan
}
/member pwwn/ {
    printf ",%s", $3
}
END {
    print ""
}'
```

このスクリプトでは、 printf ステートメントで、カンマを使って列を区切っています。最初の printf ステートメントは、zone nameとvsanを出力します。2番目の printf ステートメントは、メンバーPWWNを出力する際にカンマを追加します。最後に、最後の行を出力するために print "" を使用して、最後の行に改行を追加します。

同様に、このスクリプトをファイルに保存して、実行権限を付与し、実行してください。出力は、表の列がカンマで区切られた形式になります。

## スクリプト生成(Excel VBA)

### 質問

インプットは"yyyymmdd.txt"という、"zone show"の結果が記載されたファイルの前提で、Excel VBAのスクリプトを教えてほしい

### 回答

以下は、ファイル名が"yyyymmdd.txt"のファイルから"zone show"の結果を読み取り、テーブル形式に変換するExcel VBAのスクリプトの例です。このスクリプトでは、ファイルを開いて、内容を配列に読み込んでいます。

```vb
Sub ParseZoneShowFromFile()
    ' ゾーン情報が記載されたファイルを開く
    Dim filePath As String
    filePath = "C:\path\to\yyyymmdd.txt"
    Dim fso As Object
    Set fso = CreateObject("Scripting.FileSystemObject")
    Dim file As Object
    Set file = fso.OpenTextFile(filePath, 1)
    Dim fileContents As String
    fileContents = file.ReadAll
    file.Close
    
    ' ゾーン情報を行に分割する
    Dim lines() As String
    lines = Split(fileContents, vbCrLf)
    
    ' 新しいワークシートを作成し、最初の行にヘッダーを追加する
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Sheets.Add(After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count))
    ws.Range("A1").Value = "zone name"
    ws.Range("B1").Value = "vsan"
    ws.Range("C1").Value = "member pwwn"
    ws.Range("D1").Value = "member pwwn"
    ws.Range("E1").Value = "member pwwn"
    
    ' 行をループし、ゾーン情報を解析する
    Dim row As Long
    row = 2
    Dim zoneName As String
    Dim vsan As String
    Dim memberPwwn(2) As String
    Dim i As Integer
    For i = 0 To UBound(lines)
        If InStr(lines(i), "zone name") > 0 Then
            ' ゾーン名とVSAN番号を解析する
            zoneName = Trim(Split(lines(i), ":")(1))
            vsan = Trim(Split(lines(i), ":")(3))
        ElseIf InStr(lines(i), "member pwwn") > 0 Then
            ' メンバーPWWNを解析し、ゾーン情報をワークシートに書き込む
            memberPwwn(i Mod 3) = Trim(Split(lines(i), ":")(1))
            If i Mod 3 = 2 Then
                ws.Range("A" & row).Value = zoneName
                ws.Range("B" & row).Value = vsan
                ws.Range("C" & row).Value = memberPwwn(0)
                ws.Range("D" & row).Value = memberPwwn(1)
                ws.Range("E" & row).Value = memberPwwn(2)
                row = row + 1
            End If
        End If
    Next i
    
    ' テーブルをフォーマットする
    ws.ListObjects.Add(xlSrcRange, ws.Range("A1:E" & row - 1), , xlYes).Name = "ZoneTable"
    ws.ListObjects("ZoneTable").TableStyle = "TableStyleLight9"
    ws.Cells.EntireColumn.AutoFit
End

```

## スクリプト生成(Python Pandasなし)

### 質問

同様のスクリプトをPythonで作って

### 回答

以下は、ファイル名が"yyyymmdd.txt"のファイルから"zone show"の結果を読み取り、テーブル形式に変換するPythonスクリプトの例です。このスクリプトでは、ファイルを開いて、内容を行ごとに読み込んでいます。

```python
import csv

# ゾーン情報が記載されたファイルを開く
file_path = "yyyymmdd.txt"
with open(file_path, "r") as file:
    file_contents = file.readlines()

# ゾーン情報を行に分割する
lines = [line.strip() for line in file_contents]

# ヘッダーとテーブルの行を初期化する
header = ["zone name", "vsan", "member pwwn", "member pwwn", "member pwwn"]
table = []

# 行をループし、ゾーン情報を解析する
zone_name = ""
vsan = ""
member_pwwn = ["", "", ""]
for line in lines:
    if "zone name" in line:
        # ゾーン名とVSAN番号を解析する
        zone_name = line.split(":")[1].strip()
        vsan = line.split(":")[3].strip()
    elif "member pwwn" in line:
        # メンバーPWWNを解析し、ゾーン情報をテーブルに追加する
        pwwn = line.split(":")[1].strip()
        member_pwwn.append(pwwn)
        if len(member_pwwn) == 3:
            table.append([zone_name, vsan] + member_pwwn[:3])
            member_pwwn = ["", "", ""]

# テーブルをCSVファイルに書き込む
with open("output.csv", "w", newline="") as file:
    writer = csv.writer(file)
    writer.writerow(header)
    writer.writerows(table)

```

## スクリプト生成(Python Pandasあり)

### 質問

Pandasなどのライブラリを使って高速化できる？

### 回答

はい、Pandasを使うことで高速かつ効率的にデータの加工や集計ができます。

以下は、Pandasを使ってファイルを読み込み、データフレームに変換してから必要な情報を取り出し、最終的にCSVファイルに書き込む例です。

```python
import pandas as pd

# ゾーン情報が記載されたファイルを読み込む
file_path = "yyyymmdd.txt"
df = pd.read_csv(file_path, sep='\n', header=None, names=['line'])

# ゾーン名、VSAN番号、メンバーPWWNを取得するための正規表現パターン
zone_pattern = r'^zone name : (.+) vsan : (\d+)$'
pwwn_pattern = r'^\s+member pwwn : ([\w:]+)$'

# テーブルに変換するためのリスト
table = []

# 行ごとに処理
zone_name = None
vsan = None
member_pwwn = ['', '', '']
for line in df['line']:
    # ゾーン名、VSAN番号の場合
    if re.match(zone_pattern, line):
        zone_name, vsan = re.findall(zone_pattern, line)[0]
    # メンバーPWWNの場合
    elif re.match(pwwn_pattern, line):
        pwwn = re.findall(pwwn_pattern, line)[0]
        # メンバーPWWNをリストに追加
        member_pwwn.append(pwwn)
        # メンバーPWWNが3つになったらテーブルに追加
        if len(member_pwwn) == 4:
            table.append([zone_name, vsan] + member_pwwn[1:])
            # メンバーPWWNをリセット
            member_pwwn = ['', '', '']

# テーブルをデータフレームに変換
df_table = pd.DataFrame(table, columns=['zone name', 'vsan', 'member pwwn', 'member pwwn', 'member pwwn'])

# データフレームをCSVファイルに書き込む
output_path = 'output.csv'
df_table.to_csv(output_path, index=False)

```

このように、Pandasを使うことで、ファイルの読み込みやデータの加工・集計が高速かつ簡単に行えます。

# おわりに

ChatGPTを使ってプロトタイピングや壁打ちが捗る、というように言われているように、インフラ系の作業においても超効率的に物事を勧められるようになりますね。わずか数分で、シェルとVBAのスクリプト両方が作れるなんてすごい時代になったもんだ。。

でも、個人的には(冒頭にも書きましたが)気兼ねなく使える実行例がすぐに引っ張り出せる、というのが一番かも。
私用のPCのほうがいろいろやりやすいけど、もとになる実行結果が手元にないから頑張って目コピしてたので。