如何在Shell中解析文本文件指定段落并构建数组?
Got it, let's figure out how to parse those multi-line user blocks into a shell array—since you already know how to handle single-line key-value pairs with grep and cut, this is just a step up for multi-line content.
First, let's assume your users.txt looks something like this (filling in the blanks based on your description):
Authorized Admins:
admin1
admin2
admin3
Regular Users:
user1
user2
1. Use awk to extract the target block (cleanest method)
awk is built for handling line ranges, so it's perfect here. This command will grab all lines between the Authorized Admins: header and the next section header (assuming section headers end with a colon):
# Populate the admins array admins=($(awk '/Authorized Admins:/ {flag=1; next} /:$/ {flag=0} flag' users.txt)) # Verify the array contents echo "Total admins: ${#admins[@]}" for admin in "${admins[@]}"; do echo "- $admin" done
Here's the breakdown of the awk logic:
/Authorized Admins:/ {flag=1; next}: When we hit the target header, flip a flag to "active" and skip the header line itself/:$/ {flag=0}: When we hit a line ending with:(the next section header), flip the flag to "inactive"flag: Only print lines where the flag is active
2. Use grep with context (if sections are separated by blank lines)
If your users.txt uses blank lines to split sections, like this:
Authorized Admins:
admin1
admin2Regular Users:
userA
You can use grep's -A flag to pull lines after the header, then filter out the unwanted content:
admins=($(grep -A 100 "Authorized Admins:" users.txt | grep -vE "Authorized Admins:|^$|Regular Users:"))
-A 100: Grab the header plus the next 100 lines (adjust the number if you have more admins)grep -vE ...: Exclude the header line, blank lines, and the next section's header
Pro Tip for tricky usernames
If your usernames might include spaces or special characters, don't use ($(...)) to populate the array—it'll split on spaces. Instead, read lines one by one with a while loop to preserve each username as a single array element:
admins=() while IFS= read -r line; do admins+=("$line") done < <(awk '/Authorized Admins:/ {flag=1; next} /:$/ {flag=0} flag' users.txt)
内容的提问来源于stack exchange,提问作者Gavin Morton

