2

This question already has an answer here:

I have a file containing a list of users and information, each line is a separate user written like so:

alfred,butler,male,70,7:15. 

I want to grab the names only from the list so I can create a user for them.

Once I have the names I can simply use a for loop and echo useradd with each of the usernames then simply copy and paste the text. How do I approach grabbing the characters before the first comma?

marked as duplicate by Sergiy Kolodyazhnyy command-line Feb 5 '17 at 19:52

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

1

Extracting the names is easy: use awk with -F flag to print first field

awk  -F, '{print $1}' input.csv

In order to actually add users, you need to read output of awk , line by line. One way to do so is how Zanna shows, with pipe to while read variable ; do . . . done.

Alternative would be to take advantage of awk's system() function to create command first and pass it to the function. Consider this:

$ awk -F ',' '{command=sprintf("useradd \"%s\"",$1);print command  }' input.txt                                          
useradd "alfred"
useradd "johnny"

For each line we extract first word and put it into useradd "%s". That can be given to system() function and it will run with /bin/sh

Running this as root:

$ awk -F ',' '{command=sprintf("useradd \"%s\" ",$1); system(command) }' input.txt
$ grep 'alfred' /etc/passwd
alfred:x:1001:1001::/home/alfred:

CAUTION: system() calls /bin/sh , which on Ubuntu is symlink to /bin/dash. Therefore avoid bashisms in the command you pass

  • Separately that works perfect, in order for me to grab it and throw it in a loop i'm having a little trouble. I tried doing the following: for i in {1..1000}; do echo useradd 'awk -F, '{print $1}' file.csv'; done – Danny Feb 5 '17 at 19:36
  • @Danny because you're using wrong loop and approaching it in wrong way. You need to use while loop as Zanna shows, or system() command in awk. I'll edit my answer in a second to show those – Sergiy Kolodyazhnyy Feb 5 '17 at 19:40
  • @Danny edit done – Sergiy Kolodyazhnyy Feb 5 '17 at 19:49
1

You could use cut to grab the first field and then pipe into a while loop to run commands with the names as input:

cut -d ',' -f1 file | while read line; do echo "$line"; done

obviously this script is not doing anything useful as it is - replace echo with whatever you want to do to each name, for example sudo useradd (after testing with echo)

Explanation

  • -d ',' use comma as delimiter (d)
  • -f1 the first (1) field (f)
  • while read line reading from the file, loop over each line as variable $line
  • do <command> "$line" execute <command> on the argument expanded from the variable (ie on each line of the piped output)
  • Thank you! That executed exactly how I wanted it do. So I can actually part away by learning from this the -d and -f1 do what exactly (on their own). I understand that before the pipe it's cutting before the comma. – Danny Feb 5 '17 at 19:42
  • So if i'm understanding this correctly then -d is saying use ',' as the sepperator and f1 as the first field. The while loop runs through each line and the do executed each line one by one as it ran through. With that being said I could use the very same command to grab the the the third column by using -f3. Would it be possible to grab only female users of male users with this command within the third column? – Danny Feb 5 '17 at 21:11

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