Thursday, November 21, 2024

Hướng dẫn xử lý mảng nâng cao giữa Bash và Python

-

Tôi có một danh sách đầu vào như dưới, yêu cầu hãy đưa danh sách IP tương ứng với các group vào mảng bằng script. Ví dụ group “glusterfs” nó sẽ được định nghĩa là một biến của mảng và mảng “glusterfs” sẽ có các phần tử là 10.10.0.91 và 10.10.0.92.

cat > ./input.txt << 'OEF'
glusterfs
10.10.0.91
10.10.0.92
Ws02mi
10.10.0.21
10.10.0.22
database
10.10.0.101
10.10.0.102
OEF

Cách viết script xử lý như sau.

Cách 1: Các nhóm tự định nghĩa.

#!/bin/bash
unset glusterfs
unset Ws02mi
unset database

# Đọc dữ liệu từ file vào mảng
readarray -t lines < input.txt

# Xử lý mảng
group=""
for line in "${lines[@]}"; do
    if [[ $line =~ ^[[:alpha:]] ]]; then
        # Nếu dòng đầu tiên của một nhóm, in ra thông tin của nhóm trước đó (nếu có)
        if [ -n "$group" ]; then
            if [[ $group == "glusterfs" ]]; then
                glusterfs+=($ips)
            elif [[ $group == "Ws02mi" ]]; then
                Ws02mi+=($ips)
            elif [[ $group == "database" ]]; then
                database+=($ips)
            fi
        fi
        # Đặt tên cho nhóm mới
        group="$line"
        # Khởi tạo danh sách địa chỉ IP mới
        ips=""
    elif [ -n "$line" ]; then
        # Nếu không phải dòng trống, thêm địa chỉ IP vào danh sách
        ips+="$line "
    fi
done

# Thêm các IP cuối cùng vào mảng
if [[ $group == "glusterfs" ]]; then
    glusterfs+=($ips)
elif [[ $group == "Ws02mi" ]]; then
    Ws02mi+=($ips)
elif [[ $group == "database" ]]; then
    database+=($ips)
fi

# In thông tin của từng nhóm
echo "glusterfs: ${glusterfs[*]}"
echo "Ws02mi: ${Ws02mi[*]}"
echo "database: ${database[*]}"

Đoạn script trên có chức năng đọc dữ liệu từ file input.txt, sau đó phân loại các địa chỉ IP vào các nhóm glusterfs, Ws02midatabase tương ứng.

Đầu tiên, 3 biến glusterfs, Ws02midatabase được khởi tạo và đặt giá trị ban đầu là unset để xóa mọi giá trị cũ trong trường hợp chạy lại đoạn script.

Sau đó, đoạn script sử dụng lệnh readarray để đọc dữ liệu từ file input.txt và lưu vào mảng lines.

Tiếp theo, với mỗi phần tử line trong mảng lines, đoạn script sẽ kiểm tra xem line có phải là dòng đầu tiên của một nhóm hay không bằng cách kiểm tra xem line có chứa ký tự đầu tiên là một chữ cái hay không. Nếu có, đoạn script sẽ in ra thông tin của nhóm trước đó (nếu có) và thêm các địa chỉ IP vào mảng tương ứng.

Nếu line không phải là dòng đầu tiên của một nhóm, đoạn script sẽ kiểm tra xem line có phải là dòng trống hay không. Nếu không phải, đoạn script sẽ thêm địa chỉ IP vào mảng ips tương ứng với nhóm hiện tại.

Khi đọc hết dữ liệu từ file input.txt, đoạn script sẽ thêm các địa chỉ IP cuối cùng vào mảng tương ứng.

Cuối cùng, đoạn script sẽ in ra thông tin của từng nhóm bao gồm danh sách các địa chỉ IP trong nhóm đó.

Như vậy trong script mình phân biệt được nhóm và địa chỉ IP là do sử dụng một số quy tắc như sau:

  • Nếu dòng đầu tiên của một nhóm bắt đầu bằng một chữ cái, thì đó là tên của nhóm. Ví dụ: “glusterfs”, “Ws02mi”, “database”,…
  • Nếu dòng không phải là dòng đầu tiên của một nhóm, và không phải là dòng trống, thì đó là một địa chỉ IP.

Và đây là kết quả sau khi chạy xong đoạn script.

$. script.sh 
glusterfs: 10.10.0.91 10.10.0.92
Ws02mi: 10.10.0.21 10.10.0.22
database: 10.10.0.101 10.10.0.102

Cách 2: Các nhóm tự động nhận diện.

#!/bin/bash
data="glusterfs
10.10.0.91
10.10.0.92
Ws02mi
10.10.0.21
10.10.0.22
database
10.10.0.101
10.10.0.102"

# tach data thanh tung group
groups=()
group=""
while read -r line; do
  if [[ $line =~ ^[a-zA-Z]+ ]]; then
    if [[ ! -z $group ]]; then
      groups+=("$group")
    fi
    group="$line: "
  elif [[ $line =~ ^[0-9\.]+$ ]]; then
    group+="$line "
  fi
done <<< "$data"
groups+=("$group") # them group cuoi cung

# in ra danh sach IP cua moi group
for g in "${groups[@]}"; do
    for hoanghd in "${g[@]}"; do
        echo "$hoanghd"
    done
done

Cách hoạt động như sau:

Đây là một script bash được sử dụng để tách các địa chỉ IP từ chuỗi dữ liệu được định dạng theo nhóm. Cách thức hoạt động của script như sau:

  • Khởi tạo biến data chứa chuỗi dữ liệu ban đầu.
  • Tạo một mảng groups để lưu trữ các nhóm. Tạo một biến group để lưu trữ từng nhóm, bắt đầu với một chuỗi rỗng.
  • Sử dụng vòng lặp while để đọc từng dòng trong chuỗi data.
  • Nếu dòng đó bắt đầu bằng một chuỗi chữ cái (sử dụng regex), nghĩa là đó là tên của một nhóm, thì sẽ thêm nhóm hiện tại vào mảng groups (nếu tồn tại), và tạo một chuỗi mới để lưu trữ nhóm tiếp theo.
  • Nếu dòng đó là một địa chỉ IP (sử dụng regex), thì thêm địa chỉ IP đó vào chuỗi của nhóm hiện tại.
  • Sau khi đã đọc hết chuỗi data, thêm nhóm cuối cùng vào mảng groups.
  • Sử dụng hai vòng lặp for để in ra danh sách các địa chỉ IP của từng nhóm.

Lưu ý: Các comment trong script đã giải thích chi tiết cách hoạt động của từng phần của script.

Kết quả:

$. script.sh 
glusterfs: 10.10.0.91 10.10.0.92 
Ws02mi: 10.10.0.21 10.10.0.22 
database: 10.10.0.101 10.10.0.102

Cách 3: Sử dụng python.

#!/usr/bin/python3
import re

data = """glusterfs
10.10.0.91
10.10.0.92
10.10.0.93
Ws02mi
10.10.0.21
10.10.0.22
Ws02mi
10.10.0.21
10.10.0.22
database
10.10.0.101
10.10.0.102"""

groups = {}
current_group = None
for line in data.split("\n"):
    # Kiểm tra nếu dòng là tên group
    if not re.match(r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", line):
        current_group = line.strip()
        groups[current_group] = []
    else:
        groups[current_group].append(line.strip())

# In ra danh sách IP của từng group
for group, ips in groups.items():
    print(f"{group} IPs: {ips}")

LEAVE A REPLY

Please enter your comment!
Please enter your name here

4,956FansLike
256FollowersFollow
223SubscribersSubscribe
spot_img

Related Stories