Assuming your files have one user and one group per line, here's a pseudo-oneliner:
sed = groups.txt | while true ; do
read line_no
read group_name
[ -z $line_no ] && break
(( from = (line_no - 1) * 30 + 1 ))
(( to = line_no * 30 ))
sed -n "${from},${to} p" users.txt | xargs -r -n 1 usermod -a -G $group_name
done
This code calls sed(1) to print line number (starting with 1) and the line itself (i.e. the group name) for each line in groups.txt, then pipes that output into an endless loop, which does the following:
- Reads line number from the piped input into
$line_no variable
- Reads group name from the piped input into
$group_name variable
- If
$line_no is empty, assumes we've reached an end of groups.txt and break-exits the loop
- Calculates starting and ending line numbers for
users.txt using $line_no as index
- Calls
sed(1) to print all lines from users.txt between those lines
- That list of usernames is piped into
xargs(1), which runs usermod(8) for each single username, appending it to a $group_name from above. '-r' switch tells xargs(1) to not run usermod(8) if the username/stdin is empty.
edit: replaced semicolons with line breaks for legibility