Issue
I wanted to create a variable for each grep regex line from Usernames.txt file. The text contains this
mario,visitor
bobmarley,staff
luigi,visitor
hailey,visitor
and so on.
I want the name from before the comma as a username and visitor as the group for the user
#!/bin/bash
sudo addgroup visitor
sudo addgroup staff
filename='Usernames.txt'
while read line; do
username=$(echo $line | grep -o '^[a-z]*[^,]')
group=$(echo $line | grep -o '[^,][a-z]*$')
sudo useradd $username -G $group -p $username
done < $filename
but the output says command username not found. So instead I tried not so efficient method
while read line; do
sudo useradd $(echo $line | grep -o '^[a-z]*[^,]') -G $(echo $line | grep -o '[^,][a-z]*$') -p $(echo $line | grep -o '^[a-z]*[^,]')
done < $filename
I want the result of each loop to be like this
sudo useradd mario -G visitor -p mario
How do I improve this? Thanks!
Solution
Forking of multiple processes (e.g. grep
) on every single loop iteration is a bad idea in general. Also, simple word splitting can be done directly in Bash, without any external processes.
Option 1:
while IFS= read -r line; do
username="${line%,*}"
group="${line#*,}"
echo sudo useradd "$username" -G "$group" -p "$username"
done < "$filename"
Option 2:
while IFS=, read -r username group; do
echo sudo useradd "$username" -G "$group" -p "$username"
done < "$filename"
Answered By - Andrej Podzimek Answer Checked By - Gilberto Lyons (WPSolving Admin)