0

Need to set a function which receives a username, location in the table and the new value to set. the table set is

user:value1:value2:value3

I realize how I can do the replace using awk '{gsub... but no idea how to specify it on a specific user.

1 Answers1

3

First of all, if the file in question is /etc/passwd, DON'T use this solution; use usermod.

Let's say you want to convert the third field along into newvalue2 for user007. You could do it like so:

awk -F: -v OFS=: '$1 == "user007" {$3 = "newvalue2"} {print}' inputfile > outputfile

If you specifically want to set a shell function to do this, you can (though I personally wouldn't bother.)

myfunc() {
  [ "$#" -eq 2 ] ||
    { printf '%s\n' 'Usage: myfunc <USER> <GPA>' 'Assigns given GPA to USER (in column 5 of "~/students.dat")'
      return 1;}

  local mytempfile
  mytempfile="$(mktemp)"

  awk -F: -v OFS=: -v user="$1" -v gpa="$2" '$1 == user {$5 = gpa} {print}' ~/students.dat > "$mytempfile" &&
    mv "$mytempfile" ~/students.dat
}

However, this is NOT something I would do for REAL data, only for temporary or "toy" data of no use to anyone but me. It's much more fragile than it should be. CSVs are no substitute for a proper database.

If you do go with a CSV-based solution, at the very least make sure you have regular backups and MUCH better error checking than shown in the above; for example, you may want to check the validity of the "user" name provided, or throw an error if the user isn't found in the CSV file, or do data integrity checks—such as range checking—on the provided GPA. But all of these things would be better done with an actual database.

You can set up a PostgreSQL sandbox very easily and start playing around with it to learn more about real databases and what you can do with them.

Wildcard
  • 35,316
  • 26
  • 130
  • 258
  • Thanks. I want to save it in the original file (data.dat), so at the end it should be data.dat >data.dat? The file has some existing users, won't redirecting it like that will overwrite everything? – Itay Gurvich Dec 04 '16 at 04:33
  • @ItayGurvich, DON'T do `... data.dat > data.dat`. See http://unix.stackexchange.com/q/185596/135943 – Wildcard Dec 04 '16 at 05:22
  • This method doesn't work for me even with a temporary file, it just creates a blank one. What am I doing wrong? `read user read gpa awk -F: '$1 == $user {$5 = $gpa}' students.dat > temp` – Itay Gurvich Dec 04 '16 at 20:23
  • @ItayGurvich, oops! See edit. – Wildcard Dec 04 '16 at 21:21
  • Great! that solved the blank file, but it still just copies the content of the file into the temp file without editing. – Itay Gurvich Dec 05 '16 at 00:28
  • @ItayGurvich, you seem to misunderstand [the difference between Awk variables and shell variables](http://unix.stackexchange.com/a/254304/135943). I'll update my answer in a moment. – Wildcard Dec 05 '16 at 03:15