6

I'm trying to sort my users into specific servers, so what I'm trying to do at the moment is grab all the users by gender. Essentially I would have one server with all male users and one with all female users. The data in the file per line is read as so:

jimlee,7676,jim lee,sony,male,8912,1543,33:44

The command I'm using below grabs the first field and then adds the user. However my goal is to add a specific gender only and create a user for them. So seeing how the fifth field is the gender field I know that using -f5 will give me that field and would display all the users by gender but I'm not sure how to grab the name based on a specific field, in this case the fifth field (gender).

cut -d ',' -f1 file.csv | while read line; do sudo useradd "$line"; done
  • 1
    Its very clunky, but you could just use grep to pre-filter for male or female eg grep male file.csv | cut -d ',' -f1 | while read line; do sudo useradd "$line"; done – Nick Sillito Feb 5 '17 at 22:08
  • 1
    Unfortunately the word 'male' is in the word 'female' so doing male grabs all the users. – Danny Feb 5 '17 at 22:15
  • Good point! change the grep to grep ,male, – Nick Sillito Feb 5 '17 at 22:16
  • 1
    @NickSillito then grep -w male would help, so it just matches the full word. – fedorqui Feb 6 '17 at 13:17
7

Carrying over from my previous answer in your other question How to grab characters before comma in a list and export to a script? , use awk with $FIELD == "word". Here male and female are set in field 5

awk -F',' '$5=="male" {command=sprintf("useradd \"%s\" ",$1); system(command) }' input.txt

You can do same for "female"

  • I think you need to add -F , after "awk", and command= before "sprintf" – Nick Sillito Feb 5 '17 at 22:35
  • Yes. Wrote it out by hand because I'm on phone. I'll fix that – Sergiy Kolodyazhnyy Feb 5 '17 at 22:57
  • @Serg don't you still need to assign the sprintf result to the command variable? – steeldriver Feb 6 '17 at 0:24
  • @steeldriver yes, another thing that i fixed – Sergiy Kolodyazhnyy Feb 6 '17 at 1:35
7

You could try

sudo awk -F , '($5=="male") {system("useradd " $1)}' file.csv
2

If you want to search for a pattern and fields may be inconsistent (ie if gender might not always be in the 5th field), you could use a sed way to grab the first field if female is in any field, for example:

sed -nr 's/^([^,]+),.*,female,.*/\1/p' file

Explanation

  • -n don't print until we ask for something
  • -r use ERE
  • s/old/new replace old with new
  • ^([^,]+), save some characters before a comma at the start of each line (the first field)
  • ,.*, any number of any characters that might occur between two commas (so it doesn't matter how many fields there are between the first field and the pattern)
  • ,female, the line will only match if this pattern occurs
  • \1 the saved pattern in () from earlier
  • p print only the lines that we changed
2

It's probably quite straight forward to simply use a Bash loop with comma as field separator and calling useradd when required:

while IFS=, read user f2 f3 f4 gender _;
do
    if [ "$gender" == "male" ]; then
         sudo useradd "$user"
    fi
done < file

No need to call external commands such as awk or sed.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.