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
, Ws02mi
và database
tương ứng.
Đầu tiên, 3 biến glusterfs
, Ws02mi
và database
đượ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ếngroup
để 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ỗidata
. - 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ảnggroups
. - 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}")